OmniAICreator/Qiita-1.07M huggingface dataset:
Windowsのクリップボード上の画像をOCRしてクリップボードに文字で保持するコンソールプログラムを書いてみた

# TL;DR;

Windows10, 11で、クリップボードに画像としてコピーされているものから、文字を抽出し、クリップボードに文字として保存するコマンドの例です。

## 例

例えば、以下のようなものが「画像」として送られてきたとき、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65002/704d0a00-66d8-a8ea-a81f-6ca684148cc7.png)


Windows-Shit-Sなどで画像をクリップボードに保存してから、本稿のコマンドを実行すると、読み取られた文字がクリップボードに入ります。文字おこしとしては期待している内容ではないところもあるものの、検索エンジンにざっくり投げてみるくらいには使えそうではないでしょうか。

```
RunnabIe(){pubIic void run(){throw new NuIIP0interException() } . run() ・ lang . NuIIPointerException 1. run ( # 2 : 1 ) at ( # 2 : 1 ) 一 例 外 java. jshell> new
```

# モチベーション

エラー文字列をスクショで報告された場合、その画損を見ながら自分で文字にするのが面倒なことがありますが、最近のWindowsにはOCRの機能がついているので、文字に変換するまでは省力化できるのでは?と考え、試してみたくなりました。

# 書いたもの

## リポジトリ

こちらです。
[https://github.com/hrkt/ReadCharsInClipboard](https://github.com/hrkt/ReadCharsInClipboard)


## 動作前提

- 日本語のWindows 10, 11だと動くと思います。

# 作り方

## 依存するWindows OSの機能

["Windows.Media.Ocr"](https://docs.microsoft.com/ja-jp/uwp/api/windows.media.ocr?view=winrt-22621)がベースです。

## 利用したツールと環境

- Visual Studio 2022
- Windows 11 Pro 22H2 (OS ビルド 22622.590)

## コード例

提供されているOCRエンジンを使い、指定した言語（例では日本語(ja-JP)決め打ち）で、画像から文字として読めるものを抽出します。

```csharp
        static String tryReadChars(SoftwareBitmap bitmap)
        {
            // execute OCR
            // TODO: It might be better to change the language setting by OS settings.
            OcrEngine engine = OcrEngine.TryCreateFromLanguage(new Windows.Globalization.Language("ja-JP"));
            var result = engine.RecognizeAsync(bitmap);
            result.AsTask().Wait();

            OcrResult ocrResult = result.GetResults();
            return ocrResult.Text;
        }
```

Windowsのクリップボードの画像を取得してOCRに入力する画像にするところは、以下のように書きました。

```csharp
        static SoftwareBitmap GetImageFromClipboard()
        {
            if (!Clipboard.ContainsImage())
            {
                return null;
            }

            System.Drawing.Image image = Clipboard.GetImage();
            MemoryStream ms = new MemoryStream();
            image.Save(ms, ImageFormat.Bmp);
            var decorder = BitmapDecoder.CreateAsync(ms.AsRandomAccessStream());
            decorder.AsTask().Wait();

            BitmapDecoder bitmapDecoder = decorder.GetResults();
            Windows.Foundation.IAsyncOperation<SoftwareBitmap> asyncOperation2 = bitmapDecoder.GetSoftwareBitmapAsync();
            asyncOperation2.AsTask().Wait();

            SoftwareBitmap bitmap = asyncOperation2.GetResults();

            return bitmap;
        }
```

## もしも動かしてみたいとき

ビルドしたものを以下に置いておきます。
https://github.com/hrkt/ReadCharsInClipboard/releases/tag/v0.1.0

- 何か文字が含まれる画像を作って（Windows-Shift-Sで画面の一部をクリップボードにコピーするなどして）
- コマンドを実行し
- 結果としてクリップボードに入った文字列をエディタなどにCtrl-Vで張り付けるなどして確認してください。

# おわりに

以下のような点について試してみてもいいかもしれません。

- コマンドを（コンソールからではなく）何らかのショートカットから起動する
- OCRのエンジンを引数などで指定し、使い分けられるようにする

ネタとしては満足したので、本稿はここまででいったん筆をおきます。

# 参考

- [Windows.Media.Ocr 名前空間](https://docs.microsoft.com/ja-jp/uwp/api/windows.media.ocr?view=winrt-22621) Windowsで装備されているOCRライブラリ
- [ microsoft /
Windows-universal-samples ](https://github.com/Microsoft/Windows-universal-samples/tree/main/Samples/OCR) OCRライブラリのサンプル
paizaラーニング レベルアップ問題集 ソートメニュー応用編 JavaScript 区間のソート

区間のソート (paizaランク C 相当)

https://paiza.jp/works/mondai/sort_advanced/sort_advanced__problems_simple_boss

sliceで区間を切り出します。

解答コード例
```javascript:JavaScript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//数列の長さを表す整数 n 
//ソートする区間の左端の位置を表す l と右端の次の位置を表す r 
const [n, l, r] = lines[0].split(" ").map(Number);
//数列 a
const a = lines[1].split(" ").map(Number);
//数列 a の l 番目の要素から r - 1 番目の要素だけを昇順でソート
const aSorted = a.slice(l, r).sort((a, b) => a - b);
//操作後の数列 a を半角スペース区切りで出力
console.log(aSorted.join(" "));
```
paizaラーニング レベルアップ問題集 ソートメニュー応用編 JavaScript 重複削除

重複削除 (paizaランク C 相当)

https://paiza.jp/works/mondai/sort_advanced/sort_advanced__problems_simple_step3

集合Setで重複削除をします。スプレッド構文で配列に変換します。

解答コード例
```javascript:JavaScript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//数列の長さを表す整数 n 
const [n, k] = lines[0].split(" ").map(Number);
//数列 a
const a = lines[1].split(" ").map(Number);
//数列 a から重複した要素をすべて削除
let set = new Set([...a]);//集合Setで重複削除
//残った要素を昇順かつ半角スペース区切りで出力
console.log([...set].sort((a, b) => a - b).join(" "));//スプレッド構文で配列に変換
```
paizaラーニング レベルアップ問題集 ソートメニュー応用編 JavaScrip Top - k (easy)

Top - k (easy) (paizaランク C 相当)

https://paiza.jp/works/mondai/sort_advanced/sort_advanced__problems_simple_step2

解いてみました。
大きい順に並び替えて、k番目に大きい値を出力します。

解答コード例
```javascript:JavaScript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//数列の長さを表す整数 n 
const [n, k] = lines[0].split(" ").map(Number);
//数列 a
const a = lines[1].split(" ").map(Number);
//数列 a を降順でソート
a.sort((a, b) => b - a);
//数列 a の k 番目に大きい値を出力
console.log(a[k - 1]);
```
paizaラーニング レベルアップ問題集 ソートメニュー応用編 JavaScript 最大最小

最大最小 (paizaランク C 相当)

https://paiza.jp/works/mondai/sort_advanced/sort_advanced__problems_simple_step1

解いてみました。

# 解答コード例(昇順)
昇順に並べ替えて、末尾が最大値、先頭が最小値です。
```javascript:JavaScript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//数列の長さを表す整数 n 
const n = Number(lines[0]);
//数列 a 昇順でソート
const a = lines[1].split(" ").map(Number).sort((a, b) => a - b);
//a の最大値、 a の最小値の順で、半角スペース区切りで出力
console.log(a[n - 1], a[0]);
```

# 解答コード例(降順)
降順に並べ替えて、先頭が最大値、末尾が最小値です。
```javascript:JavaScript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//数列の長さを表す整数 n 
const n = Number(lines[0]);
//数列 a 降順でソート
const a = lines[1].split(" ").map(Number).sort((a, b) => b - a);
//a の最大値、 a の最小値の順で、半角スペース区切りで出力
console.log(a[0], a[n - 1]);
```
Ruby 3.2 で Set が組込みクラスになる？

Array クラスの陰に隠れて存在感の薄い Set クラスですが，みなさん使ってますか？

Set クラスは文字どおり数学の「集合」を表すクラスです。標準添付ライブラリーなので（組込みではないので），`require` しないと使えません。

Set の影が薄い理由は，組込みクラスでないことに加え，集合にまつわるだいたいのことが Array で代用できてしまう，ということがあると思います。
これは，Array が「大クラス主義」的に設計されていて，他言語なら分けて設計するようなさまざまなデータ型の機能を Array に詰め込んでいるからですね。

しかし，「Set は要素の重複が無いことが確実」なのに対し，Array で集合を表すと要素の重複があるかもしれないので，最後に `uniq` をかます必要があったりします。
やはり集合のようなデータは Set クラスで表すのがよさそうです。
でも `require` が面倒。

なのですが，どうやら Ruby 3.2 で Set が組込みクラスになるようです。
https://www.ruby-lang.org/en/news/2022/09/09/ruby-3-2-0-preview2-released/
https://bugs.ruby-lang.org/issues/16989

現在，Ruby 3.2 は 3.2.0-preview2 が出ていて，Linux や macOS の人は rbenv で気軽にこの preview2 を試すことができます。
私もこれをインストールしてやってみました：

```terminal:Ruby 3.2.0-preview2 にて
% ruby -e "p (1..4).to_set & Set[2, 4]"
#<Set: {2, 4}>
```
たしかに `require` 無しで `to_set` や `Set[ ]` が使えました。

しかし，よく分からんのは，set ライブラリーって，いまは gem で提供されてるんですよね。
gem 形式の組込みクラスなんてあるの？

`pp` メソッドなんかは，これもやはり gem 形式のライブラリーで提供されているのですが，呼ばれると自動的に `require` されるようになっています。なので `Kernel` に最初から組み込まれているかのように使えるんですよね。これと似たようなものなのかな？
paizaラーニング レベルアップ問題集 ソートメニュー応用編 JavaScript ソートの基本

ソートの基本 (paizaランク C 相当)

https://paiza.jp/works/mondai/sort_advanced/sort_advanced__problems_simple_step0

解いてみました。問題文に従って、`a_1 ≦ a_2 ≦ ... ≦ a_n` かどうか判定します。

解答コード例
```javascript:JavaScript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//数列の長さを表す整数 n 
const n = Number(lines[0]);
//数列 a
const a = lines[1].split(" ").map(Number);
//a_1 ≦ a_2 ≦ ... ≦ a_n かどうか判定
let flag = true;
for (let i = 0; i < n - 1; i++) {
    if (a[i] > a[i + 1]) {
        flag = false;
        break;
    }
}
//a が昇順でソートされている場合は Yes を、そうではない場合は No を出力
if (flag) {
    console.log("Yes");
} else {
    console.log("No");
}
```
別解で、sliceやsort,everyや三項演算子を用いて解いてみました。
```javascript:別解
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//数列の長さを表す整数 n 
const n = Number(lines[0]);
//数列 a
const a = lines[1].split(" ").map(Number);

//数列 a が昇順でソートされた状態 aSorted
  //slice()でコピーを作り、数列aと連動しないようにする
const aSorted = a.slice().sort((a, b) => a - b);

//a が昇順でソートされている場合は Yes を、そうではない場合は No を出力
console.log(a.every((v, i) => v === aSorted[i]) ? "Yes" : "No");
```
暗号試算についてまとめてみた

# はじめに
IT×ビジネスという視点で週1本記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)


# 暗号試算とは
暗号試算とは、__現物のない電子データ資産__ で、法定通貨(円、ドル、ユーロ、etc...)ように国から保証されているものではありません。

# 暗号試算とブロックチェーン
暗号試算は[ブロックチェーン](https://qiita.com/7_inai_/items/2ea53163ae5ec3df9cfe)によって成り立っています。暗号試算は法定通貨と違って、銀行のような中央管理者がおらず、コンピュータのネットワークを利用して分散的に管理されています。この分散して管理するために使用する技術がブロックチェーンです。

# 暗号試算と仮想通貨
ところで、以前は __仮想通貨__ という呼び方が主流だったと思いますが、仮想通貨と暗号試算の違いは何でしょうか？
実は基本的には、仮想通貨と暗号試算に違いはありません。しかし、2018年12月に、金融庁が仮想通貨の呼称を暗号資産に改めると発表し、2020年5月1日に正式に施行されました。
名称を暗号試算に変更した主な理由は以下の2つです。
- 「通貨」という名称が日本円などの法定通貨と混同されてしまう
- 世界標準に合わせるため
->仮想通貨の用途が拡大されたことから、世界的に仮想通貨の名称が変更されました。これまでは __「Virtual Currency」__ だったのに対して、__「Cryptocurrency」__ という名称が使われるようになりました。

# 仮想通貨と時価総額
仮想通貨の規模を表すために、時価総額が用いられます。時価総額はよく企業価値の大きさとして用いられる指標ですが、仮想通貨の大きさを表す指標として用いることもできます。
仮想通貨の時価総額は、__仮想通貨の価格×発行数量__ で算出することができます。
（ちなみにですが企業の時価総額は、株価×発行済みの株式数です。）
一般的には、時価総額が高いほど需要が高く信用性が高いと考えられます。
※仮想通貨の時価総額ランキングは次のようになっています。
1位：ビットコイン
2位：イーサリアム
3位：テザー
4位：USD Coin
5位：BNB
2022年9月1日時点

# ビットコインとイーサリアム
仮想通貨の時価総額で1位と2位のビットコインとイーサリアムですが、どういった違いがあるのでしょうか？
それぞれの特徴は以下の通りです。
### ■ビットコイン
・仮想通貨の中で最古
・仮想通貨の基軸通貨(価格基準となる通貨)

### ■イーサリアム
・イーサリアムとはプラットフォームのことで、そこで利用する暗号試算をイーサ(ETH)という
・[DApps](https://qiita.com/7_inai_/items/9b859520d31bff2cf1c8)(分散型アプリケーション)の開発に使用される
・スマートコントラクトを使える
　スマートコントラクト：ブロックチェーンシステム上に設定されたルールに従って自動的に取引が実行されるプログラム


# 終わりに
暗号試算についてまとめてみましたが、筆者はまだ暗号試算を購入したことがありません。どうしてもまだ投機のイメージが強く、価格が安定するまでは手の出しづらさがあります。著名人の何気ない一言や、ニュースによって価格が変動することがあるため、信頼性が低いですが、これから需要が高まっていき、多くの人が所有するようになれば、信頼性が増加し価格も安定するでしょう。そうなったときはまた購入を考えるかもしれません。
最後までお付き合いくださりありがとうございました。
ゼロからXMLを勉強しなおす1

# はじめに
UiPathでXMLファイルの形式を扱うことが多くなったことをきっかけに、
ゼロからXMLを勉強しようと思ったので、メモとして残します。

# 今回の学習メモ
今回勉強した内容です。
箇条書きでまとめています。
## XMLの特徴
* XML(Extensible Markup Language)の略称
* W3C(World Wide Web Consortium)により勧告されるメタ言語で「拡張可能なマークアップ言語」の訳
    * W3CはWWWで利用される技術の標準化を推進する団体。マサチューセッツ工科大学など大学や研究所、企業などが集まって1994年10月に発足。
    *  W3Cでは
        *  作業ドラフト
        *  勧告候補
        *  勧告案
        *  勧告
    の手順で標準化作業が進む。XMLでは現在のVer1.0が1998年に勧告された。

* 「XMLはメタ言語」といわれるが、この意味は「言語を作ることができる言語」という意味。
* 「マークアップ（文中につける印）」を使い、文章やデータの中に、別の情報を埋め込む言語」をマークアップ言語と呼ぶ。
* XMLは「自分で文中につける印を拡張し、言語（仕様？）を作る言語ということになる。

## SGMLやHTMLとの関係

* XML以前にも同じ目的でSGML（Standard Generalized Markup Language)というメタ言語が存在したが、あらゆる用途に使えるようにと考えられたため、非常に複雑で扱いづらいものだった
* その後インターネットのWebページを記述する言語であるHTML（Hyper Text Markup Language)がSGMLから作られ、W3Cに勧告された
* しかしHTMLは
    * 複数の文字コードがエンコードできない
    * 大文字と小文字を識別しない
    * 使用できるタグが固定されている
    * 終了タグのないものや省略できるもの、独自に拡張されたものがあり使用が不安定
という問題があり、様々なデータを文書中に埋め込むのは難しかった

* そこでSGMLの部分集合として不要と思われる機能を削除し、「インターネットで扱いやすい言語」としてXMLというメタ言語が開発されることとなった
* 現在はXMLで定義されたHTML（XHTML）もW3Cにより勧告されている

## データ形式
* XMLのデータは「XML文書」と呼ばれ、テキストデータで構成されている（XMLの文書ファイルはテキストファイル）→インターネットでやり取りがしやすく、直接エディタなどで内容を表示・編集することができる
* XMLがプラットフォーム（OS・実行環境）に依存しない、柔軟なデータ交換に利用できる

## XMLの応用
* XMLの応用として、
    * 社内文書
    * 仕様書
    * マニュアル
    * 製品カタログ
    などの文書データや、
    * 顧客情報
    * 受発注などのDB
    * アプリケーションのデータ
    などすべてのデータをXMLで置き換えることが考えられている
（実現すれば不特定多数の企業間による相互データ連携がインターネットを通じて可能になると考えられているため）

# おわりに
続きはまた今度書きます。
ターミナルでの作業効率がグンと上がるaliasの設定方法と設定例まとめ

# はじめに
現在新卒エンジニア1年目の私が多用している、「alias」による作業効率化を紹介します！
特に、**ターミナル上での作業が多い分野(gitやrailsなど)** でこうかばつぐんでございます。

# aliasとは
alias(エイリアス)とは、日本語で「別名」や「通称」という意味です。
aliasがどういうものかと言うと、一言で言えば**コマンドのショートカット**です。
ターミナルでよく打ち込む長いコマンドを省略して打ち込むことができます！

# aliasの設定方法
aliasは以下のコマンドで設定できます。
```shell
# aliasの書き方
$ alias {省略形}='{本来のコマンド}'

# 例) git add -Aをgaaと省略する
$ alias gaa='git add -A'
# 全変更分をstageすることができる
$ gaa

# 例) git checkoutをgcoと省略する
$ alias gco='git checkout'
# feature-123ブランチにcheckoutすることができる
$ gco feature-123
```
この例の通りにaliasを設定すると、
「gaa」と打つだけで「git add -A」を実行することができますし、
「gco {ブランチ名}」と打つだけで「git checkout {ブランチ名}」を実行することができます！
まさに普段打っている長いコマンドを、あの煩わしいコマンドを、**たった数文字にショートカット**することができます！

ただし、このコマンドは**ターミナルを閉じるとリセットされてしまう**ので、ターミナル起動時に自動で設定されるようにしましょう。
- shellが**bash**の方は`~/.bashrc`
- shellが**zsh**の方は`~/.zshrc`
に書くと自動でaliasが設定されます！

---以下bashでの例---
```shell
# vimかなにかで~/.bashrcにaliasのコマンドを追記する
$ vim ~/.bashrc

# 追記ができたら~/.bashrcを再読み込みする
$ source ~/.bashrc
```
これでターミナルを再起動してもaliasが設定できています！

# おすすめのalias設定例
あくまで一例ですので、みなさんの扱いやすい形でお使いください！
### 基本
```shell
# ~/.bashrc操作周り
alias virc='vim ~/.bashrc'
alias sorc='source ~/.bashrc'
alias carc='cat ~/.bashrc'

# originalコマンドの上書き
alias ls='ls -lahFG'
alias ps='ps aux'
alias psg='ps aux | grep'

# よく使うディレクトリへのcdショートカット
alias cddev='cd ~/src/development'
alias cdm='cd ~/src/development/rails/memo_app'
```

### git
```shell
alias g='git'
alias ga='git add'
alias gaa='git add -A'
alias gap='git add -p'
alias gb='git branch'
alias gbd='git branch -D'
alias gbm='git branch -m'
alias gcm='git commit -m'
alias gco='git checkout'
alias gcob='git checkout -b'
# masterにcheckout、masterがなかったらmainにcheckout
alias gcom='git checkout master 2>/dev/null || git checkout main'
alias gd='git diff'
alias gl='git log'
# masterをmerge、masterがなかったらmainをmerge
alias gmm='git merge master 2>/dev/null || git merge main'
alias gp='git push'
alias gpl='git pull'
alias gpo='git push origin'
alias gpuo='git push -u origin'
alias gs='git status'
alias gsa0='git stash apply stash@{0}'
alias gsl='git stash list'
alias gss='git stash save'
alias gsu='git stash save -u'
```

### rails
```shell
alias r='rails'
alias rc='rails c'
alias rdc='rails db:create'
alias rdd='rails db:drop'
alias rdm='rails db:migrate'
alias rdmr='rails db:migrate:reset'
alias rdmrds='rails db:migrate:reset db:seed'
alias rdms='rails db:migrate:status'
alias rdr='rails db:rollback'
alias rdrs='rails db:reset'
alias rds='rails db:seed'
alias rdsr='rails db:seed:replant'
alias rr='rails routes'
alias rs='rails s'
```

# おわりに
学生時代にこの技を教えてくださった先輩エンジニアの方には頭が上がりません。
Teams の Emoticons の URL 群：Adaptive Card や Power Platform で使える・・筈

# 背景
Teams には Emoticons が沢山あります。
これらを Adaptive Card や Message で使う場合用に URL を調査した結果


こういうやつです。 (yes) とか　:p とかで使えます。[ショートカットはこちら](https://support.microsoft.com/en-us/office/view-all-available-emojis-b9c2ccda-9ad9-4dbb-a25d-bbcebf6311ae)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/d9dc775e-398b-f676-c500-396c2d49034e.png)

# 更新履歴
## 2022/9/22
Teams で利用している URL を再調査して、正常化
同一URLになっているものは重複削除（ 同一 Emoticon に対し複数のショートカットがあるものがある為）

## 2022/9/19
Icon 名称でのリンク切れが多かったので改めてURL 調査してみたところ・・
名称の前に、ID らしきものがついているものが多かったので修正（全部ではないが）

修正後
> grinningfacewithbigeyes

修正前）
> 1f603_grinningfacewithbigeyes


# リンク
Codepen で、ICON 一覧を用意したので、以下で確認

https://codepen.io/baku2san/pen/abGZxbK

こんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/72c9b915-d94a-de4e-8c88-28dda81594a2.png)


## 補足
- Icon Size は 20 / 40 / 60 / 100 px がある。他にもあるかも？
- 上記リンクでは、全部載せると探すの大変になりそうだったので、40px のみとした
- MS の Icon 一覧から、ショートカット名を元にリストを作ったので、~~名称違いで抜けてるものもあるかも~~ ID 付きのものに修正

# 利用方法
## 手順
1. 欲しいアイコン上で、画像リンク取得
1. 画像サイズを、20/40/60/100 で URL 修正
1. 使うだけ

## 例
1. アイコンで画像リンク取得<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/2e690bce-347a-0c0b-755a-78fe33e5f7c9.png)
1. 画像URL修正<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/a5091630-d123-8bdd-8dec-4d80d0b36105.png)

# 参考
元々のアイコンの種類は以下で紹介

https://support.microsoft.com/en-us/office/view-all-available-emojis-b9c2ccda-9ad9-4dbb-a25d-bbcebf6311ae

Microsoft 系のアプリアイコンは以下

https://qiita.com/baku2san/items/b5f2a74654a49da14c7c

# あとがき
多すぎて全部確認なんてやってられなかったので、:p とかのアルファベット顔文字のリンクは除外してないです・・ :tired_face:
ボットネット とは

## 勉強前イメージ

マルウェア的な？

## 調査

### ボットネット とは

英語でBotnetと書き、
攻撃者がサイバー攻撃を行うようにマルウェアに感染させたコンピュータ と 攻撃者の指令が届くネットワークのことを指します。
ボットネットは大規模な攻撃ができてしまうので、大きな企業からはセキュリティ上の脅威と考えられています。
また、今までの被害から金融機関やセキュリティ情報サイトなど社会的な影響の大きいターゲットを設定していると見られています。

イメージとしては以下のような画像になります。

マルウェア感染したコンピュータ群は攻撃対象のサーバに対しては悪いことをしていますが、
真の攻撃者からは被害者です。
それでもコンピュータ群は悪くなるので、そもそもマルウェアにかからないように対策することが大切です。

![12022-09-10 ボットネット とは - diagrams.net - Google Chrom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/2e8363ec-494f-00aa-7828-bcd4f28910fb.png)


### ボットネットの対策

ボットネットのマルウェアに感染しないようにするには、いろんなマルウェアの対策を行うことが効果的です。
一つで防げるというものはないので、一つ一つ経路を潰す必要があります。

- ソフトウェアの最新化

不正な端末からの侵入を許さないように、
OSやアプリケーション、ソフトウェアなどは最新にする必要があります。
最新にすることで脆弱性に漬け込んで侵入する可能性を少なくします。

- ユーザの行動

不審なメールは開けない、また不審なリンクはクリックしないなど
基本的なサイバー攻撃に対する対策が必要です。

- IDS/IPSの利用

もし侵入されてバックドアが仕掛けられてしまったとしても遮断できるように
入られてからのさ対策も必要です。

## 勉強後イメージ

こういうセキュリティ系ちょくちょく調べてるけどほんと大体同じこと書いてあるよね。
ソフトウェアの最新化、変なメールは開かない、入ってからも遮断できるように。
どれだけ守れるかってことなのかね。

## 参考

- [ボットネットとは？その仕組みや被害例、対策について詳しく解説](https://www.lrm.jp/security_magazine/botnet_overview/)
- [ボットネット 【botnet】 ゾンビクラスタ / zombie cluster](https://e-words.jp/w/%E3%83%9C%E3%83%83%E3%83%88%E3%83%8D%E3%83%83%E3%83%88.html)
RapperBot とは

## 勉強前イメージ

マルウェア的なやつ？

## 調査

### RapperBot とは

2022年6月に発見されたsshサーバに [ブルートフォースアタック](https://qiita.com/miyuki_samitani/items/96087f8a754629c76b9c) を行うボットネットになります。

ブルートフォースアタックとは、パスワードを破るための攻撃方法としての1つで総当たり攻撃とも呼ばれます。
パスワードや暗号に関してありえるパターンをすべて入力し、突破する方法です。
また、ボットネットとは、ロボットとネットワークの造語で
感染してしまうと攻撃者の司令を送るサーバから感染したコンピュータに一斉に命令を与えられるようなものになります。

なので、RapperBotをわかりやすく言うとsshサーバに総当たり攻撃を行う攻撃になります
IoTデバイスを標的としていますが、ARM、MIPS、SPARC、x86などさまざまなアーキテクチャをターゲットにしていることがわかっています。

このボットネットは有名な Miraiボットネット というものを大幅に再利用していますが、機能等はオリジナルとは大きく違っています。
またMiraiボットネットはtelnetサーバにブルートフォースアタックしますが、
今回はsshサーバにブルートフォースアタックするように設定されています。

また他にも、sshに突破してアクセスできるようになると .ssh以下を削除して自分の証明書だけ用意し、
前から接続できていた管理者はアクセスできないようになります。

## 勉強後イメージ

これって強いパスワードを設定するしかないのかな・・・

## 参考

- [Fortinet、SSHサーバの悪用を試みるIoTマルウェア「RapperBot」に関する注意喚起](https://thinkit.co.jp/news/bn/19770#:~:text=%E3%80%8CRapperBot%E3%80%8D%E3%81%AF%E3%80%812022%E5%B9%B4,%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%81%A8%E3%81%84%E3%81%86%E3%80%82)
- [SSHにブルートフォース攻撃するマルウェア「RapperBot」急成長、Linuxデバイスは注意](https://news.mynavi.jp/techplus/article/20220808-2419092/)
【UE4】ブループリントの調べ方

【誰でも分かるブループリントの調べ方】

（＊注意！＊この記事はUnreal Engine4歴4ヶ月の人間が書いた記事です、参考にする場合は気をつけてください、多分大丈夫なはずです）
（初めてのQittaなので、まあ、生暖かい目で見てください...）

＿＿＿＿＿＿
東京でケーキを食べたい！！
そうしたら皆さんは美味しいケーキ屋さんをググりますよね:grin:？？？？

🔍「東京　ケーキ　おすすめ」
![mezamashi897_TP_V4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2843707/f63d191a-c39c-6d05-3096-5c5ccfa27ff5.jpeg)
（これは一人でクリスマスを迎える人...）
（こうはなりたくなよ... by高校生）



＿＿＿＿＿＿＿＿＿＿
本題に入ります、はい

Unreal Engineのブループリントを調べると...
キャラクター（アクタ）を動かしたい場合…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2843707/ef7b84a6-c1c3-cc1b-5f5c-463484231c77.png)
ヒットしません...

じゃあ英語で知べてみると...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2843707/b06a4ea1-a773-f460-7ee6-78fcf61ccd9f.png)
でてきます！！

解説すると...
「actor」はキャラクター（アクタはアクタです、はい）
「location」は位置
「Set」　変えたいは「Set」です。

【おわり】
終わりです、はい
後は頑張って！！応援してるよ！（by、数学0点を取ったことがある人より）

＿＿＿＿
お借りした画像など

小振りのクリスマスケーキを見つめるクリボッチャーの写真素材 - ぱくたそ (pakutaso.com)
https://www.pakutaso.com/20211244340post-37827.html
【メモ】deinitについて

# deinitとは？
deinitはメモリの解放を意図的に行う際にクリーンアップ処理を行なってくれる。
以下が用途である。

```Swift
class Cafes {
    var cafes = [String]()

    init(cafes: [String]){
        self.cafes = cafes
    }

    deinit{
        print("deinit is called here")
    }

    func printCafes(){
        for cafe in cafes {
            print(cafe)
        }
    }

}
var cafes: Cafes? = Cafes(cafes: ["Saint Marc", "Starbucks", "Tullys", "Dotour"])
cafes?.printCafes()
cafes = nil

///以下がプリントされる
///Saint Marc
///Starbucks
///Tullys
///Dotour
///deinit is called here

```
defer文とは？

コードを読んでいく中で、deferという見慣れない関数を見かけたため、どんなものなのかを理解するためにここにメモする。

# defer文とは？
簡単に言うと、なんらかの関数の中で必ずその処理を行いたい時にそれを定義するものである。

以下が記述例である。

```Swift
func test() {
    defer {
        print("Defer is called")
    }
    print("Hello, World.")
}
deferTest()
// 【結果】
// Hello, World.
// Defer is Called
```

このようにdefer文を書くことで、その関数の実行を終える最後にdefer文が呼ばれる形となる。

# 用途
僕もあまり多用したことはないが、for文などを使って非同期処理を行う際に利用できると思う。
【UiPath】UiElement 変数を活用して改修の手間を減らす

同じUi要素にアクセスするアクティビティが複数ある場合、
**要素を探す**アクティビティと **UiElement** 変数を活用することで改修の手間を減らすことができます。
以下の例をご参照ください。


### UiElement 変数を使わない場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/96a6f736-9856-3d16-5e6c-f2fba69a3ca1.png)
上図のシーケンスでは、次の順番で処理を行っています。
①入力欄に変数 _inputValue_ を入力する。
②入力欄に入力された値を取得し、変数 _getValue_ に格納する。
③ _inputValue_ と _getValue_ の値が一致していることを確認する。
④入力欄にEnterキーを入力する。

ここで、①②④のUi要素（セレクター）は全て同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/6c3d73dc-2b49-c896-c57a-1788a20a58b6.png)
このままでも問題なく動きますが、もしUi要素に変更があった場合は①②④全てを修正する必要があります。


### UiElement 変数を使う場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/47a4ab6b-a2fa-cfa0-34a7-f6a6c7af3e57.png)

上図はセレクターを **UiElement** 変数に置き換えた例です。
処理の先頭で **要素を探す (Find Element)** アクティビティを使いUi要素を取得し、変数 _uieInputField_ に格納しています。
①②④のセレクターは以下のように要素を変数 _uieInputField_ の指定に変更しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/c087f1a7-76a9-2e53-8738-6712b4036e5f.png)

このようにセレクターを UiElement 変数に置き換えておけば、Ui要素に変更があった場合でもUi要素を取得するアクティビティだけを修正すれば済みます。
さらに、①②④が同じUi要素を使用しているというのも一目で見てわかるようになります。
変数とアクティビティが増えるという欠点はありますが、改修の手間を減らすためにも是非ご活用ください。

## 参考
https://docs.uipath.com/activities/lang-ja/docs/wait-ui-element-appear
raspbian環境でタイトルからウインドウをアクティブ化する

## 概要
ウインドウのタイトルをもとに特定のウインドウをアクティブ化する。
pywin32はWindows環境でしか使えないので、x11のコマンドをsubprocessで実行する。

## 環境
x11が標準でインストール済みのraspbianで実行

## コード
~~~Python
import subprocess

def active_window(title):
    # xwininfoを用いて対象アプリのウインドウIDを取得する
    # https://hk29.hatenablog.jp/entry/2021/08/15/182010 から引用
    cmd_list = ['xwininfo', '-root', '-tree', '|', 'grep', title]
    cmd = ' '.join(cmd_list)
    result = subprocess.run(cmd, encoding='UTF-8', shell=True,
                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    app_id = result.stdout.split()[0]
    
    # xdotoolを用いて、ウインドウIDから対象アプリをアクティブ化
    cmd_list = ['xdotool', 'windowactivate', app_id]
    cmd = ' '.join(cmd_list)
    subprocess.run(cmd, shell=True)

if __name__ == '__main__':
    active_window('Minecraft')
~~~

## 詳細
### subprocessのざっくりした理解
subprocessは他アプリの実行ができるライブラリ。
`subprocess.run("実行コマンド")`やら`subprocess.popen("実行コマンド")`やらでコマンドの実行ができる。
`run`は起動したアプリを終了させるまで処理が進まないのに対して、`popen`は終了を待たずに処理が進む。

上記のコードは`run`で実行しているが、コードから他のアプリを起動してpyautoguiを使ってそのアプリの操作したいとかになると`popen`でやった方がいいのかもしれない。

### 使用したsubprocessのオプション
オプションを`shell=True`とするとシェルからコマンドを実行してくれる。
デフォルトは`shell=False`で、実行コマンドにexeファイル等のパスを入れるとそのまま実行してくれる

`stdout=subprocess.PIPE, stderr=subprocess.PIPE`とすることで、実行したコマンドを戻り値として取得することができる。このとき、`encoding='UTF-8'`としておかないと出力がバイナリ値で返ってくる。

### xwininfoを使ってウインドウIDを取得する
実際に使ったコードはhttps://hk29.hatenablog.jp/entry/2021/08/15/182010 の引用
~~~Python
    cmd_list = ['xwininfo', '-root', '-tree', '|', 'grep', title]
    cmd = ' '.join(cmd_list)
    result = subprocess.run(cmd, encoding='UTF-8', shell=True,
                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    app_id = result.stdout.split()[0]
~~~

`xwininfo`はウインドウ情報の取得に使えるx11のライブラリ。
オプションでウインドウのサイズや位置を取得することもできる。
参考url：https://kledgeb.blogspot.com/2012/12/ubuntu-xwininfo-1.html

`-name`オプションでタイトルを指定して使うのが楽だけど、完全一致でないと使えなくなるので`'-root', '-tree'`オプションでルートウインドウに連なるすべてのウインドウ情報を取得して、その中から特定の文字列を含むウインドウのみを`| grep "タイトル"`で抽出している。

この出力はウインドウID以外の情報も含む文字列だが、splitした1つ目でIDが取得できる。
タイトルがスペースを含んでいるとそこも分割されるので、サイズや位置を取得したい場合は注意が必要。

### xdotoolを使って対象アプリをアクティブ化
~~~Python
    cmd_list = ['xdotool', 'windowactivate', app_id]
    cmd = ' '.join(cmd_list)
    subprocess.run(cmd, shell=True)
~~~
xdotoolはウインドウの操作に使えるx11のライブラリ。
参考url：https://mackro.blog.jp/archives/9856283.html

## 最後に
非Windows環境で指定したアプリをアクティブ化することができるようになった。
今後、pyautoguiを使った作業の自動化をしていくつもりだけども、pyautoguiの使い方を解説するサイトでは同時にpywin32も使われがちなので似たようなことをまたやることになるかも。
govcの小ネタ：ゲストOSへのキーボード入力を自動化する

# TL; DR

```powershell
> govc vm.keystrokes -vm photon-ova -s 'echo \"hello, world!\"'
> govc vm.keystrokes -json -vm photon-ova -c KEY_ENTER
```

![vm-keystrokes-result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239887/e1657d6f-ba9c-7b42-ccb0-6bec3ada5c78.png)

# はじめに

VMに対する作業で毎回Webコンソールをポチポチやるのにつらみを感じたので、[govc](https://github.com/vmware/govmomi/tree/master/govc) を使って自動化してみました。

# バージョン

- vSphere: 7.0u3
- govc: v0.29.0
- ゲストOS: VMware Photon OS 4.0

# govc vm.keystrokes

このコマンドを使うと、VMのゲストOSにキーボード入力を送信できます。

```powershell
# ダブルクォーテーションはエスケープが必要
> govc vm.keystrokes -vm photon-ova -s 'echo \"hello, world!\"'
> govc vm.keystrokes -json -vm photon-ova -c KEY_ENTER
```

webコンソールで確認すると、コマンドが確かに実行されています。

![vm-keystrokes-result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239887/e1657d6f-ba9c-7b42-ccb0-6bec3ada5c78.png)

ご覧の通り送信方法は2種類あり、改行等特殊文字を送る必要がある場合は `-c` しか使えません。

|オプション|内容|
|-|-|
|`-s`|文字列を直接指定|
|`-c`|文字列をアスキーコードorエイリアス[^1]で指定|

vmがパワーオフ状態等で文字入力できなかった場合はエラーが返ります。`$?` をチェックして後続処理を打ち切れば、スクリプトで複数行コマンドを流す際も安全です。

```powershell
> govc vm.keystrokes -vm vm1 -c KEY_ENTER
govc.exe: ServerFaultCode: vim.fault.InvalidPowerState
> echo $?
False
```

# おわりに

以上、ゲストOSへのキーボード入力を自動化する方法でした。
うまくスクリプトを組めば、ログインから初期設定まで一気通貫で自動化できそうです。

[^1]: エイリアス一覧は `govc vm.keystrokes -h` で確認できます（記事中の `KEY_ENTER` もエイリアスです）。
Iterator Protocolとは？

普段配列や辞書型を利用していながら、Iteratorについて深く考えたことがなかったので、こちらにメモを残す。

# Iteratorとは？
Iterateとは日本語に訳すと「繰り返す」という意味となる。
実際に繰り返すと聞いてパッと思い浮かぶのは、for文だと思うが、事実for文を使う際もIteratorプロトコルにそのデータ構造が準拠している必要がある。

実際にfor文を使った簡単なコードを記述する。

```Swift
var cafes = ["Saint Marc", "Starbucks", "Tullys", "Dotour"]

for cafe in cafes {
    print(cafe)
}
//以下がプリントされる
// Saint Marc
// Starbucks
// Tullys
// Dotour
```

実は何気なく使っているfor文も実際はSyntax Sugarでしかなく、隠蔽されて内部的にIteratorプロトコルが使われている。
隠蔽されていない場合、どうなるか以下に記述してみた。

```Swift
var cafes = ["Saint Marc", "Starbucks", "Tullys", "Dotour"]
var items = cafes.makeIterator()
while let ite = items.next() {
    print(ite)
}
//以下がプリントされる
// Saint Marc
// Starbucks
// Tullys
// Dotour
```

# 自分でIteratorプロトコルに準拠したIteratorを作ってみる。

内部の構造をさらに理解するために、自分自身でIteratorを作ってみた。
```Swift
var items = cafes.makeIterator()
while let ite = items.next() {
    print(ite)
}

struct CafeLists: Sequence {
    var cafes = ["Saint Marc", "Starbucks", "Tullys", "Dotour"]

    func makeIterator() -> some IteratorProtocol {
        return MyIterator(cafeLists: self)
    }
}
struct MyIterator: IteratorProtocol {
    typealias Element = String
    let cafeLists: CafeLists
    var index: Int = 0

    init(cafeLists: CafeLists){
        self.cafeLists = cafeLists
    }

    mutating func next() -> String? {
        guard index < cafeLists.cafes.count else { return nil }
        defer { index += 1 }
        return cafeLists.cafes[index]
    }
}

let caffes = CafeLists()
var caffe = caffes.makeIterator()

while let item = caffe.next() {
    print(item)
}
//以下がプリントされる
// Saint Marc
// Starbucks
// Tullys
// Dotour
```
POがGoogle UX Design Certificateに挑戦してみた話(2022年7月29日合格)

# はじめに
私は、スクラムチームでPOをしています。業務上、UXデザイナーと会話する機会が多く、次第にUXデザインの思想は、POにとっても、大切な考え方だと認識するようになりました。そこで、きちんとUXデザインを勉強したいと考え、ネットで調べてみて、その時はじめて　「Google UX Certificate」　の存在を知りました。


https://ja.coursera.org/professional-certificates/google-ux-design


結果から言うと、2022年5月の中旬ごろから開始し、2022年7月２９日に合格しました（というか、最後までやり遂げました）。

https://www.credly.com/badges/f696a18d-5b74-45ac-90d5-5e393a18d95a/public_url

この記事では、Google UX Certificateがどういうもので、その結果が何が得られたのかを簡単にまとめました。

# Google UX Certificateの内容

箇条書きします。
- 全７つのコースで構成されています。
 1. Foundations of UX Design
 1. Start the UX Design Process: Empathize, Define, and ideate
 1. Build Wireframes and Low-Fidelity Prototypes
 1. Conduct UX Research and Test Early Concepts
 1. Create High-Fidelity Designs and Prototype in Figma
 1. Responsive Web Design in Adobe XD
 1. Design a User Experience for Social Good & Prepare for Jobs

- 各コース内では、次のように進めていきます。日本語はありませんが、テキストを事前に翻訳してインプットしたり、英語の字幕を使えば理解できます。
 1. Google社員によるビデオ解説
 1. テキスト解説
 1. 簡単なテキストテスト　（合格点を取れなくても、何度でもやり直せます。その場合面倒ですが。。）
 1. コース5,6,7では、FigmaやAdobeXDを使った実際のデザイン作成　と　他の受講者のレビュー

# Google UX Certificateの魅力

私が感じた魅力をお伝えします。

- 多くのGoogle社員のデザイナーが登場し、自分の言葉でわかりやすく説明してくれます。様々な経緯で、Google社員になり、皆さん最初からプロフェッショナルではないことには共感を持ち、自分にも勇気を与えてくれました。そして、いつも狭い世界にしかいない自分に高いモチベーションを与えてくれました。

- UXデザインを体系的に学べること。実際の現場において、全ての工程や手法を使うことはないですが、プロジェクトに応じて、様々な引き出しを持つことができたことは為になったと思います。受講中に実際のプロジェクトでフィードバックできるものはがあれば、すぐに試したりもしました。やはり、実際の現場で経験しないと分からないこともあります。最終的にツールを使ってプロトタイプを作成しますが、その前段階の工程がとても大切になってきます。

- FigmaやAdobeXDのツールを使って実際にデザインできること。受講前から実際のプロジェクトでもFigmaは触っていたのですが、考え方や実際の細かい技術的なところはとても参考になりました。Figmaが使えれば、AdobeXDも簡単に利用できます。これらは無料のアカウントが用意されているので、安心してください。

- 自分のポートフォリオサイトを作成できること。自分がやり遂げたものを公開するは達成感があります。特にUXデザインを仕事にしたい人には、とても役立つことでしょう.


# 感想

- デザイナーでなくても、私のようなPOや開発者にとっても、時間とやる気があれば、ぜひおすすめしたいです。特に、スクラムチームは一人ひとりがUXデザインの知識があると、より価値ある製品・サービスを作り出すことに役立つことでしょう。今回の体験によって、間違いなく私のPOとしてのキャリアを飛躍できるきっかけになったと思っています。チャンスがあれば、副業としてUXデザインをやってみたいと思っているぐらいです:relaxed:

- コースは７つですが、中身はかなりのボリュームなので、情熱がないと継続できないかもしれません。わたしの場合は、前半楽しみながらできたのですが、後半は早く完了したいという気持ちに変わり、少し情熱が下がりましたが、それでも毎日凝縮できたおかげで一気に進めました。ただ、通常は6ヶ月という期間らしいので、ゆっくりと進めていけば、継続しやすいと思います。

- 受講前に日本語版がないことに悩んだのですが、、実際に始めてだめだったら、すぐに辞めればよいという気持ちではじめました。進めていくうちにそれほど苦ではなく、反対に英語の勉強になりました。英語の勉強のために、同じビデオを複数回観たこともあります。

# 最後に

次回以降、各コースごとに、重要となるポイントについて、解説できたらと考えています。
最後まで読んでくださって、ありがとうございます。
【Docker】コンテナ内でcron実行させる

## はじめに
Dockerコンテナ内でcronを利用してバッチ処理を行うための設定を備忘録として残します。
開発環境構築時にわざわざコンテナに入ってcrontabを修正するような手順を省くための手順です。

## 環境

|  | version |
|:-:|:-:|
| PHP  | 8.0.10  |
| Laravel Framework  |  8.83.23  |
| Docker Compose  | 2.10.2  |

## 前提
Laravelがインストールされているコンテナ内でcronが実行されていること。
Laravelのcommandを登録済みであること（`php artisan make:command`）。

## 手順
#### 定期的に実行させたい処理を登録

```app/Console/Kernel.php
class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        Hogehoge::class,  // 実行させたいクラス
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('example:test') // 毎分 example:test を実行する
            ->everyMinute();
    }

```
#### 一度Dockerコンテナに入り、cronの設定を確認・コピーする
```
crontab -l
```

ついでにcron設定の保存先を確認（おそらく `/var/spool/cron/crontabs/` 配下）。


#### cronの設定を記述したファイルを作成, Dockerビルド時にコピーするコマンドを追記

```crontab
# min	hour	day	month	weekday	command
*/15	*	*	*	*	run-parts /etc/periodic/15min
0	*	*	*	*	run-parts /etc/periodic/hourly
0	2	*	*	*	run-parts /etc/periodic/daily
0	3	*	*	6	run-parts /etc/periodic/weekly
0	5	1	*	*	run-parts /etc/periodic/monthly
# 以下追記
*   *   *   *   *   cd /data/www/laravel-project/ && /usr/local/bin/php artisan schedule:run 
```

```Dockerfile
# rootユーザーのcron設定としてコピー
COPY ./docker/php/crontab /var/spool/cron/crontabs/root
```

#### 最後に
`docker compose build`して`cron`の設定がコンテナに反映されており、Laravelのジョブが実行されているかを確認。

## 参考
https://reffect.co.jp/laravel/laravel-task-schedule-cron
times文を用いた繰り返し処理問題

問題
times文を使って、以下のようにターミナルに出力されるプログラムを書く。

1回目の繰り返し
2回目の繰り返し
3回目の繰り返し
4回目の繰り返し
5回目の繰り返し
6回目の繰り返し
7回目の繰り返し
8回目の繰り返し
9回目の繰り返し
10回目の繰り返し

自分の答え
10.times do|i|　
　　puts "#{(i+1)}回目の繰り返し"
end

正解
10.times do|i|　
　　puts "#{i+1}回目の繰り返し"　
end

修正が必要な点
ブロック変数+1の式展開は、（）が不要。

式展開
文字列の中に式を入れることができる機能。
式展開する場合は、文字列を””で囲む必要があり、’’で囲んでも機能しない。
Sequenceプロトコルを振り返る

普段からArrayやDictionaryを使っていたが、Sequenceプロトコルとはなんなのかをしっかり理解できていないで使っていたため、ここで基礎的な部分を振り返る。

# Sequenceとは？
Sequenceとは、その要素に一方向からアクセス可能なデータのことを言う。
ArrayやDictionaryなどもその先頭のインデックスから順次アクセスできるので、シーケンスプロトコルに準拠しているといえる。

Sequenceプロトコルには以下のような関数が存在する。

forEach(_:)メソッド　→　要素に対して順次アクセスする
filter(_:)メソッド　→　要素を絞り込む
map(_:)メソッド　→　要素を変換する
flatMap(_:)メソッド　→　要素をシーケンスに変換し、それを一つのシーケンスに連結する
compactMap(_:)メソッド　→　要素を、潮お会いする可能性のある処理を用いて変換する
reduce(_:)メソッド　→　要素を一つにまとめる

# Collectionプロトコルとは？
Sequenceのプロトコルも存在するが、それに対してCollectionプロトコルも存在する。
Collectionプロトコルとは、あるSequenceを包含しているプロトコルである。

Sequenceとは英語で連続、Collectionは英語で一つの塊と訳していると考えると理解しやすいと思う。
実際にCollectionの持つプロパティに以下のものが含まれる。

isEmptyプロパティ → コレクションが空かどうか
countプロパティ → 要素の個数を数える
firstプロパティ → 最初の要素を取得する
lastプロパティ → 最後の要素を取得する
初投稿

どこかの記事で毎日コードを書くのが良いと書いていました。
また、一か月に一度違う言語を勉強するのが良いと書いていたのを見たので
今日から、毎日コードを書く＋新しい言語を学ぶにチャレンジします。
そんな成長？過程を見て頂ければとおもいます。

Python

print('Hello World')

first_contact = Hello World
print(first_contact)


プリントを使いハローワールドを表示しました。
【関数を列or行に適用】numpyのapply_along_axisでfor文を無くそう【Python】

# はじめに
ある日のこと、業務でめちゃくちゃ処理が遅いなぁと思いコードをのぞいてみると2重のfor文を発見:confounded:

何とかできないかと探したときに出会ったのが私とapply_along_axisとの出会いです！

apply_along_axisで何ができるかといいますと、、、ずばり<INS>「関数をnumpy配列の列or行ごとに適用できる」</INS>です！

ということで今回はnumpyのapply_along_axisを紹介します！

# 環境
- Google Colaboratory
    - Python 3.7.13
    - numpy 2.21.6

# 問題設定
今回は[公式ドキュメント](https://numpy.org/doc/stable/reference/generated/numpy.apply_along_axis.html)を参考にかなりシンプルな処理で試してみます。

まず乱数を使って100000×3のサイズのnumpy配列を用意しました。

```python
import numpy as np

arr = np.random.randint(1, 10, (10**5, 3))
print(arr[:5])

>>
array([[6, 2, 9],
       [2, 2, 7],
       [8, 1, 8],
       [9, 3, 8],
       [3, 8, 9]])
```

出力は100000行の内先頭5行を表示しています。

そして適用させたい関数が以下です。
```python
def func(a):
  return (a[0] + a[-1]) * 0.5
```
この関数は1次元配列の先頭の値と末尾の値を足して0.5を掛けるシンプルな関数となっています。

:::note info
今回の目標は「関数funcを配列arrの行ごとに適用させること」です！
:::

※ちなみに
今回の例でいうと関数など使わずに以下コードで済んでしまいます。

```python
result = (arr[:, 0] + arr[:, -1]) * 0.5
result[:5]
>> array([7.5, 4.5, 8. , 8.5, 6. ])
```

より複雑な関数を適用させたいとき、apply_along_axisの真のありがたみに気づくでしょう:innocent:



# for文を使った方法
for文を使って1行づつ処理をした場合が以下コードです。

```python
result = np.array([])
for a in arr:
  calc = func(a)
  result = np.append(result, calc)
result[:5]

>> array([7.5, 4.5, 8. , 8.5, 6. ])
```

実行してみると7秒ほどかかりました。

# apply_along_axisを使った方法
ではapply_along_axisを使ってみます。

```python
result = np.apply_along_axis(func, 1, arr)
result[:5]

>> array([7.5, 4.5, 8. , 8.5, 6. ])
```

こちらは1秒もかからずに計算が終わりました。

引数は適用させたい関数、軸、関数を適用する配列の順です。

# 発展
funcの0.5だった部分を引数bで指定できるとします。

```python
def func(a, b):
  return (a[0] + a[-1]) * b
```

この場合はfunctoolのpartialを使うとよいです。

```python
from functools import partial

_f = partial(func, b=0.5)

result = np.apply_along_axis(_f, 1, arr)
result[:5]

>> array([7.5, 4.5, 8. , 8.5, 6. ])
```

partialでfuncの引数bを予め固定することで同様にapply_along_axisを使うことができます。

# 最後に
読んでいただきありがとうございます。

今回はnumpyのapply_along_axisについてかなりざっくりとした説明となりましたが、本記事が誰かのためになれば幸いです:blush:

# 参考
https://numpy.org/doc/stable/reference/generated/numpy.apply_along_axis.html
【VSCode】Sticky Scrollの設定方法

## Sticky Scroll　とは
Sticky Scrollを有効化することでHTMLやJavaScriptなどで以下のように表示されるようになります。

![スクリーンショット 2022-09-12 20.11.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/dd6dd624-d4e2-3fd6-aa33-431820ceadb7.png)


## 有効化
Sticky Scrollを有効かするには設定を開いて`Sticky Scroll`と検索します。

![スクリーンショット 2022-09-12 20.13.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/39b1e56c-4114-9be3-b01f-3baa677255df.png)

`Sticky Scroll: Enabled`にチェックをつけます。

`Sticky Scroll: Max Line Count`で最大行数を設定することもできます。
夏の読書感想文＠素のJavaScriptによる実践オブジェクト指向

:qiitan:Qiitaの公式イベント **[「エンジニア夏休み企画！～自由研究や読書感想文を発表しよう～」](https://qiita.com/official-events/6d31965c499a69377c0b)** の参加記事です

# ずるさせてください
本記事では、2022年8月30日に開催された[Saitama.js vol.3【初心者歓迎 JavaScript LT会】](https://saitamajs.connpass.com/event/238897/)にお邪魔させてもらった際に登壇した、読書感想LTの資料を転載しています

https://saitamajs.connpass.com/event/238897/

zoomでの開催でしたので、イベントのアーカイブは残っておりません。。
connpassのページに他の登壇者様のスライドもありますので、そちらでイベントの雰囲気を感じていただけたらと思います…！

# 登壇資料（書評と読書感想文）
<script async class="speakerdeck-embed" data-id="390cb6473ec04825a555b976d9ef64aa" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

## 登壇資料に掲載しているURLまとめ
- ROM専 Twitter
    - https://twitter.com/rom1000_yksbpn

- 技術書典マーケット

https://techbookfest.org/product/5173846357311488?productVariantID=4791737553780736

- BOOTH

https://booth.pm/ja/items/1514854
rails 7でdevice を使用するとusersモデルに独自で追加したカラムが保存されない。


先日の[watnow](https://github.com/watnows)のハッカソンでアプリを開発をした際にRails 7.0.3を利用して開発しました。
ハッカソンで作ったアプリでログイン機能をrails7かつdeviceで実装するという選択をしたところハッカソンにおいて貴重な2時間を失ってしまいました。その際に得た知識が誰かの役にたてばなと思い記事にさせていただきました。

### 環境
Rails 7.0.3
Ruby 3.1.2 

## 状況
Rails 7でdeviceでアカウント登録する際に独自に追加したカラムが保存されないという状況にハマりました。form_withを使用して実装しており、deviceが用意してくれているemailやnameといったカラムは保存されます。



## エラー内容
deviceを使用してuserをcreateすると以下のようなエラーが出ました。
``` terminal:ログ
Started POST "/users" for ::1 at 2022-08-07 16:52:12 +0900
Processing by Devise::RegistrationsController#create as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"name"=>"ノスケ", "email"=>"aaaa@email.jp", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "faculty"=>"1"}, "commit"=>"Sign up"}
  TRANSACTION (0.0ms)  begin transaction
  User Exists? (0.2ms)  SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "nosuke@aaa.jp"], ["LIMIT", 1]]
  TRANSACTION (0.0ms)  rollback transaction
  Rendering layout layouts/application.html.erb
```

## 解決方法
deviceのコントローラー周りを見たりdbを見たり色々していたのですが解決せず
原因がRailsのバージョン7のせいで起こっているのではないかと思いました。

[deviceのissue](https://github.com/heartcombo/devise/issues/5446)を見てみると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880777/8523710f-8dd5-265f-626d-1ee0eb9e4953.png)

とのこと。
Rails7からturboがdefaultで導入されたみたいなのですが、deviceがturboに対応しておらずリクエストを送るときに`turbo: false`にしないといけないとのことでした。


## 感想
開発記事が調べにくい最新のバージョンにgemを利用することはハッカソンにおいてアンチパターンなのかもしれないと思いました。短期的な開発スピードが必要なことは明らかでRails7を使用することにためらいはありましたが、結果的に悪感的中。Herokuにデプロイする際もRailsのバージョンが関係しておりつまづいてしまったので次回のハッカソンの時には気をつけたいと思いました。しかしそういうことも含めてハッカソン楽しかったです。

## 参考記事

https://github.com/heartcombo/devise/issues/5446

https://qiita.com/jnchito/items/5c41a7031404c313da1f#devise%E3%81%8Cturbo%E3%81%AB%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84
【Git】rebaseを使う

# はじめに
Gitを触り始めたばかりの初心者です。
rebaseについて最近勉強してるので自分の考えをまとめておきます。

間違っていたらコメントで教えていただけると嬉しいです。

# rebaseとは
このようなイメージをしています。
果たしてあっているのでしょうか笑
![無題41_20220912191631.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/342b3e40-956a-c8e9-99a4-543bf0e7e09a.png)

# 使い方
## 標準
```:ターミナル
git rebase {ブランチ名}
```

## コンフリクトを解消して続行
```:ターミナル
git rebase --continue
```

## 中断
```:ターミナル
git rebase --abort
```

## rebase前に戻す
```:ターミナル
git reset --hard ORIG_HEAD
```

:::note info
rebase後のプッシュは後ろに`-f`をつける！
:::

# おわり
まだまだ機能はあると思いますが使ったことがないので記載していません。
Androidでスクロール時に他の要素と被ってしまう時の対処法

# 目次
1. はじめに
1. 解消方法
1. 解説
1. 最後に

# はじめに
スクロールを含む画面を作る際に、
iOSでは問題がないのに、
Androidだけスクロール時のレイアウトが崩れてしまう時があります。

↓Androidだけ、スクロール時に一覧部分が「クーポン一覧」のヘッダーに被っている
|iOS|Android|
|--|--|
|![ezgif-1-71832ce8b9.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/a97605de-cc60-b9e5-aef1-8e04c5438fbc.gif)|![ezgif-1-9167ce6eed.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/835429ea-51d9-b354-ac9d-0a067b0cd955.gif)|


今回は、この不具合を解消する方法をご紹介します！

# 解消方法
今回のプロジェクトは、
上からヘッダー、メイン、フッターの順番で以下のような構造になっています。

スクロールの不具合を解消するためには、
真ん中のFlexContainer（今回は`flxMain`）の設定を変更してあげるだけで解消できます。
![スクリーンショット 0004-09-12 18.29.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/d26bc1d3-e504-2f19-c72b-2ed84e62760e.png)

真ん中の要素をクリックして選択状態にしたら、
右メニューのFlexContainerタブを確認して下さい。

一番上の「**Clip Bounds**」の設定がデフォルトでOFFになっていると思うので、
ONに変更してください。
![スクリーンショット 0004-09-12 18.33.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/f468303a-7dab-f5e7-bff5-c662e07b1af8.png)


以上で完了です！

早速、動作チェックをしてみましょう。

スクロールをしても、ヘッダーに被ることなく
正常に表示されるようになりましたね！
![ezgif-1-6a2070b0c7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/0f89934f-276b-b8ad-3eed-c38f9716913b.gif)

# 解説
今回の不具合の原因を簡単に説明します:writing_hand_tone1:

FlexContainerの「**Clip Bounds**」プロパティは、
子ウィジェットが境界から出たときにはみ出た部分を
クリップ（切り取り）するかどうかを指定します。

今回の場合、
FlexContainer（親）の中に入っているセグメントWidget（子）が
スクロールする（境界から出る）時にクリップするのをOFFにしていたため、
セグメントに表示する部分がヘッダー部分に被さってしまうような動作になっていました。

親WidgetのClip Boundsを有効にすることで、
はみ出た部分をクリップし正常に表示することができるようになりました！

Clip Boundsで解決できる問題については、
こちらでも説明をしていますので併せて確認してみてくださいね:relaxed:

https://qiita.com/Kony_Team/items/f9261c929af8d5d71c69

# 最後に
FlexContainerを使っていて何故か不具合が起きる。。
という時は、Clip Boundsが起因しているかもしれません。

今回の記事を呼んで、
同様の事象に遭遇したら是非試してみてくださいね！


# 参考
https://docs.kony.com/konylibrary/visualizer/viz_widget_prog_guide/Content/FlexContainer_Properties.htm
再帰クエリ 自己テーブル parent_id

```sql
WITH RECURSIVE tree AS (
    SELECT * FROM table WHERE id = ?
    UNION ALL
    SELECT table.* FROM table,tree WHERE table.parent_id = tree.id
)
SELECT * FROM tree
```

同じテーブル内でparent_idがidの親子関係があるパターン。

取得した小孫をまとめてまとめてDELETEやUPDATEしたい場合は…

```sql
DELETE FROM table WHERE id IN (SELECT id FROM tree)
```

とする。
【Python】Pythonでネット上にあるファイルをダウンロードする方法

## 背景
- Pythonでネット上にあるファイルをDLしてカレントに保存するコードが必要になった。
- 調べて一番簡単だと思った方法をまとめておく。

## 目標
- Pythonでネット上にあるファイルをDLできるようになる。

## コード
- Pythonでネット上にあるファイルをDLする方法をまとめた以下のQuita記事さんを参考にした。
- この方が紹介されている一番簡単だと思ったコードを引用している。
https://qiita.com/toshikawa/items/2d535906b42b9332b743

```python:pythonでネット上のファイルをDLするコード
import urllib.request

#DLしたいファイルがあるurlを指定
url= "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"

#カレントディレクトリに保存したいファイル名を指定
save_name='python_iris.data'

#urllib.request.urlretrieveを使用してDL
urllib.request.urlretrieve(url, save_name)
```
※DLしているファイルはUCIのirisデータ
Fisher, R.A.. (1988). Iris. UCI Machine Learning Repository.
https://archive-beta.ics.uci.edu/ml/datasets/iris#Descriptive

## jupyetlabでやった場合
- コードだけだと、DLしたファイルの様子がわからないので、jupyterlabのスクショを添付しておく。
![file_dl_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651220/c379d630-57da-6c0f-08ba-8c1f2702b83e.png)

## おまけ　curlコマンドでDLする場合
- 言わずもがなcurlコマンドでもファイルはDLできる

```bash:pythonでネット上のファイルをDLするコード
#remoteのファイル名（iris.data）でカレントにデータを保存
!curl -O https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data

#ファイル名（curl_iris.data）を指定してカレントにデータ保存
!curl -o curl_iris.data https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data
```

![file_dl_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651220/4e08d652-2a2c-8469-6d58-9beff75d5e35.png)

## jupyterlabを黒くする方法
- この記事を参照ください。

https://qiita.com/takuma-1234/items/1f19610780ea695a519d

## 参考資料
- Fisher, R.A.. (1988). Iris. UCI Machine Learning Repository.

https://archive-beta.ics.uci.edu/ml/datasets/iris#Descriptive

https://qiita.com/toshikawa/items/2d535906b42b9332b743

## 個人ブログ

https://takuma-tech.com/2023/01/12/364/
【Visual Studio 2019】アンインストール手順

## 環境
+ Microsoft Windows 10.0.22000.856
+ Visual Studio 2019

## アンインストール手順
1. 「スタート」から `Visual Studio 2019` を検索し「アンインストール」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/5fae3dc5-c109-655c-3a70-906a2945c3f1.png)
1. `Microsoft Visual Studio Installer` を探して右クリックし「アンインストール」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/ff7be5af-abf8-a063-b155-ac8793326c2c.png)
1. アプリがデバイスに変更を加えることを許可する
1. 「アンインストール」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/4944f99a-efae-606a-55cd-3255e9178d59.png)
1. アンインストール完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/741ca55d-730c-8564-dba8-a0245dd77582.png)

## 残っているものをアンインストール
例えば `Microsoft Visual C++ 2008 Redistributable` が残っていたので同様にアンインストールする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/a76955bd-d800-7c20-b616-9d3c26c02411.png)

## 参考
https://docs.microsoft.com/ja-jp/visualstudio/install/uninstall-visual-studio?view=vs-2019#uninstall-visual-studio
RenderTextureをPNGに保存（AsyncGPUReadback利用）


```csharp
using System.IO;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.Rendering;
using UnityEngine.UI;

public class RenderTex2PNG : MonoBehaviour
{

    [SerializeField] private RenderTexture _renderTex; 
    private Texture2D _texture;

    void Update(){

        if(Input.GetKeyDown(KeyCode.A)){
            Capture();
        }

    }

    public void Capture(){

        if(_texture==null){
            _texture = new Texture2D(
                _renderTex.width,_renderTex.height,TextureFormat.RGBA32, false
            );
        }
        AsyncGPUReadback.Request(_renderTex, 0, _onRequest);

    }

    private void _onRequest(AsyncGPUReadbackRequest request){
        

        if (request.hasError)
        {
            Debug.LogError("Error.");
        }
        else
        {
            var data = request.GetData<Color32>();
            _texture.LoadRawTextureData(data);
            _texture.Apply();
        }

        var str = System.DateTime.Now.ToString("yyMMddHHmmss");
        File.WriteAllBytes( 
            $"{Application.dataPath}/image"+ str + ".png",
            _texture.EncodeToPNG()
        );

    }



}
```
Teradata Vantageのお試し環境の構築方法（まとめ）

こんにちは！ 日本テラデータ株式会社 ソリューションエンジニアの澤井です。

Vantageについてよく言われるのが「ちょっと使ってみたいけど敷居が高いんだよね…」ということ。確かにPOCをするといってもそのための打ち合わせをしたり、時にはサポートの契約をしたりと気軽にお試しできない感覚をお持ちの方は多そうです。
でもちょっと待ってください！VantageにはVantage Expressという「ちょっと使い勝手をみてみたい」という方にはうってつけの環境が用意されているのです。

クイックスタートの記事と合わせてご覧いただくことで自分だけのVantage（Express）をデプロイして、ちょっとテーブルを作ってSQLを実行してみるということが可能になります。

まずはこの先を読んでみて自分だけのVantageをデプロイしてみましょう！

# Vantage Expressの実行環境

Vantage Expressは大手クラウド・ベンダーのAmazon Web Service（AWS）、Microsoft Azure、Google Cloud Platformに用意されています。
それぞれの環境でVantageをデプロイするためのガイド記事を用意していますので、お使いのクラウド環境に合わせてご覧いただければと思います。

「これらのクラウド環境を利用するとインフラの利用料が発生するよね？」…この質問の回答は”YES”です。そのためVantage ExpressにはVMWare、VirtualBox、UTMの3つの仮想環境で動作するバージョンも用意しています。

お手軽に試せるVantage Expressを使用してぜひVantageを体感してみてください。
レッツ、トライ！！

# クラウド環境でVantage Expressを利用する
ご利用のクラウドベンダーによって以下のリンク先の記事をご覧ください。

AWSをご利用の場合
[AWSでVantage Expressをデプロイメントする](https://qiita.com/ykswi/items/fba559149ad568678d58)

Azureをご利用の場合
[AzureでVantage Expressをデプロイメントする](https://qiita.com/ykswi/items/2c30aa1f5413b16c838c)

Google Cloudをご利用の場合
[Google CloudでVantage Expressをデプロイメントする](https://qiita.com/ykswi/items/10a382de5fa5a4a42c50)

# ローカル環境でVantage Expressを利用する
ご利用の仮想環境によって以下のリンク先の記事をご覧ください

VMWare
[VMWareを使ってオンプレミスのVantage Expressをデプロイメントする](https://qiita.com/ykswi/items/ebe1d854c38db9bb0f51)

VirtualBox
[VirtualBoxを使ってオンプレミスのVantage Expressをデプロイメントする](https://qiita.com/ykswi/items/ffadaa375add309f2075)

UTM
[UTMを使ってオンプレミスのVantage Expressをデプロイメントする](https://qiita.com/ykswi/items/94995954ae723185c2f7)

# ご利用にあたってご質問がある場合

記事に書かれている内容でうまくいかなかったり、お試しいただいている中で質問したいことがでてきたり…そんあこともあろうかと思います。
テラデータではWebにフォーラムを展開しており、フォーラムに質問を記入するとテラデータのエキスパートが回答する、そんな仕組みを用意しています。

日本語でのご質問、回答ももちろん可能ですのでぜひご活用ください。

[Teradata Vantage日本語フォーラム](https://support.teradata.com/community?id=community_forum&sys_id=542c85ef87501d58c197411e0ebb35f5)

#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
154.Storageオブジェクト

# ブラウザのストレージについて
## localStrage
ブラウザの保存領域にデータを格納するためのオブジェクトのこと
### ブラウザにキーバリューを保持しておきたい
1.localStrage.setItem(キー,バリュー)
```js
localStrage.setItem('key','value');
```
確認方法
![スクリーンショット 2022-09-12 17.32.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/714631/8728ac0e-ad22-963d-d273-94ad44785a71.png)
2.Applications→Localstorage→chrome~に保存されました。
### ローカルストレージを確認
1.localStrage.getItem(キー)
```js
localStrage.setItem('key');
```

## 使用例
例えば、お気に入りやカートなど、ブラウザにキャッシュしたいものをおくといいかも
https://www.globalgate.co.jp/blog/how-to-use-localstrage
Dockerのプロキシ設定（CentOS, RHEL）

毎度忘れてしまうので、メモ。
社内プロキシ下などで`docker pull`するために必要なプロキシの設定です。

## CentOS, RHEL7系の場合

- ディレクトリ作成
```
$ sudo mkdir -p /usr/lib/systemd/system/docker.service.d
```

- ファイル作成＆環境変数設定
```
$ sudo vi /usr/lib/systemd/system/docker.service.d/http-proxy.conf
```

```ini
[Service]
Environment="HTTP_PROXY=http://user:pass@proxy.domain:port"
Environment="HTTPS_PROXY=http://user:pass@proxy.domain:port"
Environment="NO_PROXY=localhost,127.0.0.1"
```

- Docker再起動
```
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
```

## RHEL8以降の場合

Dockerの代わりに[Podman](https://podman.io/)を使うことが推奨されており、パスが若干違います。
※なお、podmanは`docker`コマンドとの互換性があるので、基本的にはDockerと同じように使えます。

- ディレクトリ作成

```bash
$ ls /usr/lib/systemd/system/podman
podman-auto-update.service  podman-auto-update.timer    podman-restart.service      podman.service              podman.socket               
```

```bash
$ sudo mkdir -p /usr/lib/systemd/system/podman.service.d
```

- ファイル作成＆環境変数設定
```bash
$ sudo vi /usr/lib/systemd/system/podman.service.d/http-proxy.conf
```

```ini
[Service]
Environment="HTTP_PROXY=http://user:pass@proxy.domain:port"
Environment="HTTPS_PROXY=http://user:pass@proxy.domain:port"
Environment="NO_PROXY=localhost,127.0.0.1"
```

- Podman再起動
```
$ sudo systemctl daemon-reload
$ sudo systemctl restart podman
```
C/C++ で浮動小数点値を高速に文字列化したいメモ

## 背景

漢はときには GB サイズの数値データを .csv とかに高速に変換せねばならぬ時がある... なるべく精度(丸め)を保ったまま...

## dtoa benchmark

https://github.com/miloyip/dtoa-benchmark

ありがとうございます! とりあえずは RapidJson 作者さまの milop dtoa 使うのがよさそうです! 10 倍高速化!


## おまけ

itoa(integer to ascii) はこちら

https://github.com/jeaiii/itoa