OmniAICreator/Qiita-1.07M huggingface dataset:
IIS の CGI でバイナリデータを返すときにハマった

ウェブアプリケーションのサーバーサイドで Excel ブックを作成する必要があり、もともと IIS (Internet Information Services) と Ruby が動作する環境があったこともあり、rubyXL を試してみることにしました。

https://github.com/weshatheleopard/rubyXL

ひとまず、次のようなプログラムを作成してみました。

```ruby
require "rubyXL"

workbook = RubyXL::Workbook.new

puts "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
puts "Content-Disposition: attachment; filename=\"filename.xlsx\""
puts

print workbook.stream.string
```

しかし、ブラウザーで開くとファイルはダウンロードされるものの、そのファイルは Excel で開くことができません。

いろいろ調べてみると、次のように標準出力をバイナリモードに変更する必要があるようです。

```diff_ruby
require "rubyXL"

workbook = RubyXL::Workbook.new

puts "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
puts "Content-Disposition: attachment; filename=\"filename.xlsx\""
puts

+ STDOUT.binmode
+
print workbook.stream.string
```

無事、空白の Excel ブックがダウンロードされるようになりました。

これは、rubyXL や Ruby であることは直接関係なく、CGI のプログラムは標準出力にデータを出力しますが、[Windows の IO にはテキストモードとバイナリモードがあり](https://docs.ruby-lang.org/ja/3.3/class/IO.html#io_binmode)、IO のひとつである標準出力にもそれらのモードがある。そして、標準はテキストモードになっているので、そのままでバイナリデータである Excel ブック（というべきか、ZIP ファイルというべきか）を出力すると壊れてしまう、と理解しています。[^1]

[^1]: テキストモードとは改行コード (`\n`, `\r\n`) を自動的に変換するモードのこと。IIS というよりは Windows の機能なので、確認はしていませんが IIS 以外のウェブサーバーでも、Windows 環境の場合は同じなのではないかと思います

いまどき CGI はあまり使われない上に、Windows 特有ということもあってか、なかなか情報がなく、たかだか 1 行ですが解決に時間が掛かりました。

## 環境

* Windows Server 2022 Datacenter
* IIS 10.0
* RubyInstaller Ruby+Devkit 3.3.4-1 (x64)

## 参考

* [夕暮ログ Ruby でバイナリデータを標準出力に出力する](http://tinqwill.blog59.fc2.com/blog-entry-98.html)
* [Ruby で CGI＞出力方法](http://sig3.org/rubycgi/output.html#A1)
* [バイナリモードとテキストモード](https://teratail.com/questions/14840)
useContextを理解する

## useContext
propsは親から子に値を渡すために使用するがpropsをたくさんの中間コンポーネントを使って値を渡す場合、バケツリレーをしなければならなかったり、たくさんのコンポーネントからの参照が必要な場合はpropsの受け渡しでは不便なものになります。

useContextを使用する目的は、useContextを使えば親コンポーネントから明示的にpropsを渡されなくとも値を受け取ることです。

## 使用方法
### 1. コンテクストを作成する。
createContextに設定する値はデフォルト値となります。
コンテクストを提供せずにコンテクストを使用していた場合はデフォルト値が使用されます。

```typescript:MyContext.tsx
import { createContext } from "react";

type User = {
  name: string;
  age: number;
};

export const MyContext = createContext<User>({
  name: "Taro",
  age: 20,
});
```

### 2. コンテクストを使用する

useContextを使用してMyContextから値を読み取るようにします。

```react:User.tsx
import { useContext } from "react";
import { MyContext } from "./MyContext";

export const User = () => {
  const { name, age } = useContext(MyContext);
  return (
    <div>
      <div>私の名前は、{name}です。</div>
      <div>年齢は{age}歳です。</div>
    </div>
  );
};

```

### 3. コンテクストを提供する
コンテクストプロバイダでラップすることで、MyContextを使用可能になります。

下記の記述はこの`<div>`の下にあるコンポーネントが MyContext の値を要求した場合、
value内の値を渡せ」とReactに伝えていることになります。
```react:App.tsx
import { User } from "./User";
import { MyContext } from "./MyContext";

export const Hook = () => {
  return (
    <div>
      <MyContext.Provider value={{ name: "Yamada", age: 30 }}>
        <User />
      </MyContext.Provider>
    </div>
  );
};
```

コードを全て合わせると画面上にはプロバイダが提供した値を表示できるようになりました。
![スクリーンショット 2024-09-03 21.31.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689023/490e957c-b507-0135-0163-ff48d51d21dc.png)



## 参考
https://ja.react.dev/learn/passing-data-deeply-with-context
Salesforceでフローを作成しよう～プロファイルシステム管理者ユーザにレコード削除させない方法

本橋孝昭です

今回はプロファイルシステム管理者ユーザにレコード削除させない方法をご説明します


プロファイルシステム管理者は
・標準プロファイルなので設定変更できない
・すべてのレコード削除可能

という設定なので、システム管理者のSalesforceユーザはすべてのレコード削除が通常では可能です。

今回はそんなシステム管理者のSalesforceユーザに対しレコード削除をさせない設定をフローで行います

## 例　プロファイルシステム管理者のユーザは取引先削除をさせない

## 完成フロー図
このようになります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/034a5acd-c539-f577-20cc-25e23973bee0.png)

1つずつ見ていきましょう


## ステップ1 開始条件を設定

開始条件は取引先レコード削除かつ
数式は
{!$User.ProfileId}="00e～"
となります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/034a5acd-c539-f577-20cc-25e23973bee0.png)

なお、"00e～"はSalesforceごとに異なります。
プロファイルＩＤはプロファイルを表示した際のＵＲＬをまず確認します

例として私の環境のID確認方法を見ていきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/bc903253-4721-2dda-0ecf-761f9b17042e.png)

このように私の環境ではプロファイルのURLは
https://resourceful-bear-nezgxo-dev-ed.trailblaze.lightning.force.com/lightning/setup/EnhancedProfiles/page?address=%2F00eF90000017ROP
でしたのでプロファイルIDの15桁は
00eF90000017ROP
となりますね

この15桁を18桁にしましょう

例としてこちらのリンクから18桁に変更するのが容易です

https://www.adminbooster.com/tool/15to18

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/6bb4b4a7-fce1-67fb-7a99-2f84581c474b.png)
これでシステム管理者の18桁のプロファイルは
・00eF90000017ROPIA2
ということが分かりましたのでこちらを設定します


## ステップ1 エラーメッセージを設定


エラーメッセージ設定はこのようにカスタムエラーを使用します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/86366e93-7493-abc4-be53-a813c114a131.png)


あとはフローを保存して有効化してください

プロファイルシステム管理者のユーザの場合
このように取引先レコード削除を試みるとエラーメッセージが出て削除不可になります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/930231fc-e163-1f84-d8d0-c83ee6a2f4b5.png)
Sodium日本語化リソースパック作ってみた！

# はじめに
どうもこんにちは！mamuDevです
今回は僕の趣味であるMinecraftの[Sodium](https://modrinth.com/mod/sodium)というfabricで使えるmodの設定guiを日本語化するリソースパックを作成したのでご紹介いしたいと思います！
# 目次
- [Sodiumとはなんぞや](https://qiita.com/hihimamu/items/28ca1aef439476008e13#sodium%E3%81%A8%E3%81%AF%E3%81%AA%E3%82%93%E3%81%9E%E3%82%84)
- [設定guiの変化](https://qiita.com/hihimamu/items/28ca1aef439476008e13#%E8%A8%AD%E5%AE%9Agui%E3%81%AE%E5%A4%89%E5%8C%96)
- [導入方法](https://qiita.com/hihimamu/items/28ca1aef439476008e13#%E5%B0%8E%E5%85%A5%E6%96%B9%E6%B3%95)
- [最後に](https://qiita.com/hihimamu/items/28ca1aef439476008e13#%E6%9C%80%E5%BE%8C%E3%81%AB)
# Sodiumとはなんぞや
forgeを使っている方にはOptifine等がお馴染みですかね？SodiumはMinecraftにおけるレンダリングに関する処理を最適化し、fpsを向上させることができるmodです。
これにより、環境によりますがfpsが数倍に飛躍します。特にShaderを導入してきれいな世界で旅をしたいというクラフターには必須のmodですね。
美麗なShaderを導入したらfpsが一桁になったりしてとてもプレイできません。
ですがこれ、**設定画面が英語**です。さらにfpsを伸ばすにはどうしたらいいのか、てんでわからないのは困りますよね。次の項目からこの記事の趣旨である日本語化Sodiumについてお伝えしたいと思います！
# 設定guiの変化
![sodium japanese setting gui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661758/daa23b6c-f151-5df2-62dc-9baa0566d979.png)
このような感じに変化いたします！
標準で日本語が用意されている部分はそのままですが、各設定に関する説明の長文に至るまですべてを日本語化しております。
# 導入方法
今回このリソースパックは[Modrinth](https://modrinth.com/)というサイトにアップロードしておりますので、[Sodium Japanese Localization](https://modrinth.com/resourcepack/sodium-japanese-localization)からご自身が導入なされてるSodiumのバージョンにあったもの(といっても現在('24/09/03)では1.21.xのみ対応です。順次追加予定)をワールドが保存されている起動構成フォルダの中のresource packフォルダの中にインストールしていただけると、問題なく使用できるかと思われます。
もし、導入できないなどございましたらgithubリポジトリの[issues](https://github.com/hihimamuLab/Sodium_JPLocalization/issues)までご報告よろしくお願いいたします。
# 最後に
この記事によってより多くの方のmodライフが充実することを願います。又、日本語訳など改善点ございましたら同上の[issues](https://github.com/hihimamuLab/Sodium_JPLocalization/issues)までよろしくお願いいたします。
この記事を読んでいただきありがとうございました！
【アイディア】小小数


## 前書き

これはアイディアです。
パクっていいです。

## 基本

小小数とは既存の小数の概念を拡張したものである。
小小数には以下の特徴がある。

1 < 1.1 = 1.1.0 < 1.1.1 < 1.1.1.1 < 1.1.11 < 1.111

## したいこと

四則演算の群が定義できるかどうか。
距離空間が定義できるかどうか。
IPアドレスでアクセスするサーバーの証明書を作成する

## はじめに

IPアドレスでアクセスするサーバーに、httpsでアクセスするための証明書を作成する手順の備忘録です。
内容としては、 https://tex2e.github.io/blog/protocol/certificate-with-ip-addr の内容です。

## 手順

### 1. 鍵を生成する

```bash
openssl genrsa -out server.key
```

以下のような感じで実行されます。

```bash
$ openssl genrsa -out server.key
Generating RSA private key, 2048 bit long modulus (2 primes)
...................+++++
............+++++
e is 65537 (0x010001)
```

### 2. 署名要求を生成する

```
openssl req -new -key server.key -out server.csr
```

プロンプトで、国、都道府県、会社名、FQDNなどを入力します。

```bash
$ openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Shizuoka
Locality Name (eg, city) []:Shizuoka
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Com
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:test.example.com
Email Address []:admin@example.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
```

### 3. SANファイルを作成する

エディタなどで以下の1行だけの `san.txt` ファイルを作成します。

```
subjectAltName = DNS:test.example.com, IP:192.168.1.101
```

### 4. 証明書を生成する

```bash
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt -extfile san.txt
```

以下のような感じで実行されます。

```bash
$ openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt -extfile san.txt
Signature ok
subject=C = JP, ST = Shizuoka, L = Shizuoka, O = Example Com, CN = test.example.com, emailAddress = admin@example.com
Getting Private key
```

### 5. 証明書のSANを確認する

```bash
openssl x509 -text -in server.crt -noout
```

コマンドの実行結果に、以下のようにSANの情報が入っていることを確認します。
```
Certificate:
    Data:
        Version: 3 (0x2)

        ...

        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:test.example.com, IP Address:192.168.1.101
```

あとは、サーバーにこれらのファイルを組み込んで使用すればOKです。
TryHackMe Writeup：Cyborg



## What is the user.txt flag?

nmapでポートスキャンするときに、-script vulnを追加すると隠しページが見つけられます

/admin　のページがあった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2152468/60c27f93-567b-7cfd-4910-a3c2182a92d4.png)

ここのArchiveからDownloadを選択するとTarファイルが手に入る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2152468/39361413-60d0-a527-6e19-242665191db9.png)


もう少しWebページを見ていく
/etc/もあることがわかったので、そこにいってみるとsquidのページがでてくる（squidはプロキシっぽいですが、よくわからない）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2152468/3818ed55-1270-1888-dbd4-96fcf9883bf5.png)


passwdを選ぶとなにやら、IDとパスワードが手に入る


Tarファイルを解凍して、いろいろ見ていくと
READMEファイルがあって、以下の記載がある
```
This is a Borg Backup repository.
See https://borgbackup.readthedocs.io/
```

つまり、このREADMEがあるフォルダはBorgというツールで圧縮されている

なので、Borgで解凍していく

以下でField（？）を出力する。パスワードはsquidでみつかったものを入れたらうまくいった！
```
borg list final_archive 
```






![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2152468/981dcb88-5186-317a-fb7b-d34ce2b25219.png)

これでＳＳＨしたらうまくいった！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2152468/999ac340-9da2-99d6-a81b-e49db469357a.png)


## What is the root.txt flag?


```
while getopts c: flag
do
        case "${flag}" in
                c) command=${OPTARG};;
        esac
done
```


```
# Print end status message.
echo
echo "Backup finished"

cmd=$($command)
echo $cmd
```


ここから以下のWriteupを参考に進めた
https://fieldraccoon.github.io/posts/Cyborg/

大きな流れは
chmod +s /bin/bash
を利用して、BashをRoot権限で使えるようにして、

bash -p 

で実際に特権モード（Root権限）でBashを開いて頑張ってroot.txtを探します


## 最後に

結構いろいろなところに情報があったり、Borgの情報収集しないといけなかったりと楽しめました！



## 補足

### chmod +s /bin/bash 
chmod +s /bin/bash コマンドは、/bin/bash ファイルに「Setuidビット」を設定するためのコマンドです。このビットの設定には以下のような意味があります。

Setuidビットの役割
chmod +s コマンドでファイルに対して「Setuidビット」を設定すると、そのファイルが実行されたときに、そのファイルの所有者の権限で実行されるようになります。

具体的には、次のような動作をします。

通常の動作:

通常、ユーザーがプログラムを実行すると、そのプログラムは実行者のユーザー権限で動作します。
Setuidビットが設定された場合:

Setuidビットが設定されたプログラムを実行すると、そのプログラムは「ファイルの所有者」の権限で動作します。
chmod +s /bin/bash の影響
/bin/bash に Setuidビットを設定することで、次のような影響があります。

Bashシェルがroot権限で実行される:
/bin/bash は通常 root ユーザーが所有しているため、Setuidビットが設定されると、どのユーザーが Bash シェルを起動しても、そのシェルが root 権限で動作するようになります。
これにより、通常のユーザーがroot権限でシェルを使用できるようになり、システム全体に対する制御権限を取得することになります。
Next.js 初期セットアップ

## パッケージインストール
### devDependenciesにインストールしたいとき
```
npm install <パッケージ名> --save-dev
```
`dependencies`と`devDependencies`を間違えてしまった時は一度アンインストールしてインストールし直す。
```
npm uninstall <パッケージ名>
```
## コードのチェックと整形
### ESLint
**①VSCode拡張機能のESLintをインストール**

**②.eslintrc.jsonについて**
`.eslintrcjson`は`.eslintrc.js`に変更可能。
基本的なルールが設定されている`eslint:recommended`を追記。
```.eslintrc.js
module.exports = {
  extends: [
    // ESLintが公式で用意している基本的なルールが記載されているため必要
    "eslint:recommended",
  ],
};
```

**③Next.jsが推奨している設定を追加**
`"next/core-web-vitals"`
https://nextjs.org/docs/pages/building-your-application/configuring/eslint
```.eslintrc.js
module.exports = {
  extends: [
      〜
    // Next.jsが推奨している設定
    "next/core-web-vitals",
  ],
};
```

### prettier
**①VSCode拡張機能のPrettier - Code formatterをインストール**

**②prettierのインストール**
```
npm install --save-dev prettier
```

**③eslint-config-prettierのインストール**
ESLintとPrittierには被っている設定があるので、ESLintのいくつかの設定をオフにしてPrittierに任せましょうということでeslint-config-prettierを用意してくれている。
https://prettier.io/docs/en/integrating-with-linters

インストールしたらextendsの一番最後に`prettier`を追記すればOK
```.eslintrc.js
module.exports = {
  extends: [
  　〜
    // ESLintにはコードの書式設定ルールも含まれており、競合する可能性があるため必要。
    "prettier",
  ],
};
```
### 自動整形
VSCord左下の設定マーク　>　設定　>　ワークスペース　>　右上の矢印がくるっとしたやつで`settings.json`を開く。
**①ESLint側の自動整形として`editor.codeActionsOnSave`を追記**
https://www.digitalocean.com/community/tutorials/linting-and-formatting-with-eslint-in-vs-code#step-4-formatting-on-save

**②Prettier側の自動整形として`editor.formatOnSave": true`を追記**

**③デフォルトのフォーマッターを`prittier`に設定**
`"editor.defaultFormatter": "esbenp.prettier-vscode"`
```settings.json
{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "eslint.validate": ["javascript"],
  "editor.formatOnSave":true,
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}
```
これでESLintによってエラーを検出されたら自動で修正され、
かつコードのフォーマットとしてPrettierを指定したのでルールに応じて自動修正してくれる。

### scriptの設定
`npm-run-all`をインストールした上でスクリプトの記述を行う。
```
npm install npm-run-all --save-dev
```
``` package.json
    //チェック（npm-run-allのインストール必要）
    //チェックする分には同時に実行して構わないので並列で実行（パラレル）
    "lint": "run-p --continue-on-error lint:*",
    "lint:eslint": "next lint",
    "lint:prettier": "prettier --check .",

    //自動修正
    //ESLintとPrettierの自動修正が同時に行われるとおかしくなるので直立で実行（シリアル）
    "fix": "run-s --continue-on-error fix:eslint fix:prettier",
    "fix:eslint": "next lint --fix",
    "fix:prettier": "prettier --write .",
```
### .prettierignoreの設定
.nextファイルも監視対象になっているので、`.prettierignore`ファイルを作成し、`.next`と記述すると対象外にしてくれる。

### huskyやlintstageの使いどき
チーム開発をするならhuskyやlintstageの導入は必要。なぜなら全員がESLintの設定がちゃんとできているとも限らないし、全員がVSCodeを使用しているとも限らないから。
だからコミットされる前に必ずESLintを通さないといけないhusky等を使用するとチームでコードの綺麗さを保つことができる。

## tailwindcss
### 簡単にイイ感じのスタイルを適用できるtailwindTYPOGRAPHY
スタイルを自動で付与してくれるパッケージ。
https://zenn.dev/datchlive/articles/50e556d27d68b4

### 順番を自動で入れ替えてくれるprettier-plugin-tailwindcss
https://github.com/tailwindlabs/prettier-plugin-tailwindcss
**①インストール**
```
npm install -D prettier prettier-plugin-tailwindcss
```

**②.prettierrc.jsを作成し、設定を記述**
```.prettierrc.js
module.exports = {
  plugins: ["prettier-plugin-tailwindcss"],
};
```
RPAとHULFT Squareの共存可能性を探る

# 目次
1.はじめに
2.RPAの簡単な説明
3.RPAとHSQ(HULFT Square)の処理内容
4.RPAとHSQ(HULFT Square)の処理比較
5.RPAとHSQ(HULFT Square)の機能比較
6.おわりに

# はじめに
最近、社外の方とお話しするとRPAについてよく耳にします。
「RPAを試しに導入したら仕事が効率化し、現場のDX意欲がわいた」
「RPAを導入したらみんなが使い始めて想定よりRPAライセンスが高くなりそう」
「RPAを現場レベルでは使用しているが、管理が難しいのでETLを導入したい」

RPAという言葉はよく聞くし、GUIベースで処理が作れるらしいですが、全然知りません。
実際のところどんななのか触ってみます。
そして、せっかくなのでRPAとHSQ(HULFT Square)の共存可能性を探っていきます。


# RPAの簡単な説明
RPAには [サーバー型・デスクトップ型・クラウド型](https://robotango.biz/knowledge/rpa-type/) といった様々な種類がありメーカーによって機能が違います。
今回はデスクトップ型の某RPAを使用しました。

PRAの種類によって機能やサポートが異なるので、導入時は下記に気を付けると良さそうです。
・プログラミング処理の有無
・接続可能なシステム種類
・テンプレート・マニュアルの豊富さ


# RPAとHSQの処理内容
### 処理内容
100行5列のExcelのデータをkintoneに読み込ませる。

#### 読み込ませるExcelイメージ図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803480/bd5611b3-6f5f-4c0a-bf05-cee0a454118e.png)

#### 読み込ませたkintoneイメージ図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803480/39984c84-9151-2ae4-2e63-a5a2194eb492.png)

#### RPAの処理方法
1.kintoneの画面をブラウザから開く。（今回は手動でログインしたが、RPAで自動化可能）
2.Excelのセルに記載されているデータをコピーし、kintoneに張り付ける。

#### HSQの処理方法
1.kintoneコネクタを設定する。
2.デザイナーを開きスクリプトを作成する。
3.Excelコネクタを使用しExcelデータを読み込む。
4.kintoneコネクタを使用し、kintoneにデータを書き込む。

:::note
HSQではExcelデータをkintoneに連携する際、ノーコードで全角を半角に変換したり四則演算したりすることが可能です。
某RPAで全角半角変換や四則演算をしようとしたところプログラミングが必要でした。
今回、HSQとRPAの処理内容を合わせるために加工処理はしません。
:::

#### HSQにて設定するkintoneコネクタ項目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803480/d78b5ebd-843f-efcb-9fff-ee2117707068.png)

#### HSQにて作成したスクリプト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803480/c88b932b-9cc4-5a79-c976-eca8cf2d7828.png)


# RPAとHSQ(HULFT Square)の処理比較
|  |HSQ|某RPA|
|:-:|:-:|:-:|
|**処理時間**|1秒845ミリ秒|10分58秒|
|**処理作成時間**|30分|30分（マニュアル確認3時間）|
|**全角半角処理**|ノーコード|プログラミング必須|


# RPAとHSQ(HULFT Square)の機能比較
|  |HSQ|某RPA|
|:-:|:-:|:-:|
|**API連携**|◎（専用コネクタ・REST API）|△|
|**DB連携**|◎（専用コネクタ）|△|
|**データ加工処理**|◎|△|
|**ブラウザからの出力**|×|◎|
|**自動処理**|システムを開くことなく自動で動く|パソコンでRPAを立ち上げる必要がある|
|**ユーザー管理**|◎|△|
|**課金体系**|リソース（CPU・メモリ等）|実行環境数|
|**導入負荷**|◎|◎|
|**処理時間**|◎|△|

RPAはすごく便利で使いやすいシステムでした。
「RPAを試しに導入したら仕事が効率化し、現場のDX意欲がわいた」という意見にも納得です。

RPAは処理中はパソコンが触れない、API連携やDB連携などのシステム連携が不得手、処理に時間がかかる。
だがWEBブラウザ操作が得意です。

HSQはバックグラウンドで処理が行える、API連携やDB連携などのシステム連携が得意、リソースを追加して処理を高速化可能。
だがWEBブラウザ操作が不得手です。

なので、WEBブラウザ操作はRPAにしてもらい、以降のAPIやDB連携はHSQが行う、という様に使い分けるとスムーズなデータ連携ができそうです。


# おわりに
記事を見ていただきありがとうございます。
初めての記事の作成のため、見出しの作り方、画像の挿入など色々手探りで書いています。
何か不足がありましたらコメントより教えていただけるとありがたいです。
Python(Django)でカバレッジレポートを作成

# はじめに

Pythonのカバレッジ測定ツール「coverage.py」を使用してカバレッジレポートを出してみました。

カバレッジとはテストの際にどのコードが実行されたかを測定し、テストがどの程度のコードをカバーしているかを示します。

### 開発環境

- Windows 11
- VS Code

# 1.カバレッジの計測準備

**1.coverageのインストール**

まず、`coverage`をインストールします。

```bash
pip install coverag
```

**2.coverageの設定**

プロジェクトのルートディレクトリに設定ファイル`.coveragerc` を作成

`.coveragerc` ファイルを作成する際の基本的な例

```
iniコードをコピーする
[run]
branch = True
source =
    myapp1
    myapp2
omit =
    */tests/*
    */migrations/*
    */admin.py

[report]
show_missing = True

```

### `[run]`セクション

- **`branch = True`**:
    
    この設定は、コードの分岐カバレッジ（条件分岐のカバレッジ）も測定することを意味します。通常のカバレッジ測定では各行が実行されたかどうかしか確認しませんが、`branch = True`とすると、`if`や`else`などの条件分岐が実際にテストされたかどうかもチェックします。
    
- **`source =`**:
    
    カバレッジを測定する対象のソースコードのディレクトリやモジュールを指定します。ここでは、`myapp1`と`myapp2`という2つのアプリケーションが対象になっています。これにより、これらのアプリケーションに対してのみカバレッジ測定が行われます。
    
- **`omit =`**:
    
    カバレッジ測定から除外するファイルやディレクトリを指定します。ここでは以下が除外されています：
    
    - `/tests/*`: テストファイルは除外されます。通常、テストコード自体がカバレッジの対象に含まれる必要はないためです。
    - `/migrations/*`: Djangoのマイグレーションファイルも除外されます。これらはデータベーススキーマの変更を管理するためのもので、通常カバレッジに含める必要はありません。
    - `/admin.py`: Djangoの管理インターフェースを構成する`admin.py`ファイルも除外されます。管理インターフェースの設定ファイルはしばしばテストの対象外とされます。

### `[report]`セクション

- **`show_missing = True`**:この設定により、カバレッジレポートでどの行がテストされなかったか（カバレッジが不足している部分）を表示します。これにより、どのコードがテストされていないかを簡単に把握することができます。
- 

# 2.カバレッジの計測

次に、`coverage`を使用してテストを実行し、カバレッジを計測します。

**1.カバレッジ計測の実行**:

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

```bash
coverage run manage.py test
```

これにより、Djangoのテストスイートが実行され、テストカバレッジデータが収集されます。

**2.カバレッジレポートの生成**:

テスト実行後、次のコマンドでカバレッジレポートを表示できます。

```bash
coverage report
```

このコマンドは、カバレッジ結果をターミナル上に表示します。各ファイルごとにカバーされている行数とパーセンテージが表示されます。

次のようなレポートが生成されます

```markdown
Name                    Stmts   Miss  Cover   Missing
-----------------------------------------------------
myapp/views.py            50     10    80%    20-25, 30-35
```

**3.HTMLレポートの生成**:

より詳細なレポートを確認するために、HTML形式のレポートを生成することも可能です。

```bash
coverage html
```

これにより、`htmlcov`というフォルダが生成され、その中にHTMLファイルが作成されます。これをブラウザで開くと、視覚的にカバレッジ率を確認できます。

# 3.HTML形式のレポートを見る

生成された`htmlcov`というフォルダの中に `index.html` があるので、VScodeで右クリックして、
エクスプローラーで表示を選択します。

そこで、ダブルクリックしてブラウザで開くことができます。
【GAS／スプレッドシート】シートをコピーした後に特定のフォーマットを初期化するコード

こんな方におすすめ

- SNS運用していてインサイトをまとめるのに毎月スプレッドシートをコピーしている
- 特定の色やフォントを毎回リセットしながら使っている

自分自身、毎月シートをコピーして使っていたのですが、日付のところで土曜日→青、日曜日→赤といった感じでフォントやカラーを変更していて（下画像参照）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524273/e2b585e8-a984-9b9b-56a7-79148234e696.png)


これを毎回変えるのってめんどいなぁと思っていたのですが、
だったらGASでやっちゃおう！ということで自作しました。

動作としてはこんな感じ
![画面収録-2023-11-08-10.59.08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524273/ef765f62-3143-ce49-c1e4-4d39d11959f4.gif)


## GASコード
```
const ss = SpreadsheetApp.getActiveSheet();

function sheet_init(){
    // アクティブなシートの1行目・2行目、D列から最終列の色をリセットする
    ss.getRange(1,4,2,31).setBackground(null).setFontColor(null);
    
    // 一列ずつ見ていって土曜の時は青、日曜の時は赤に変更
    var day_of_week = ss.getRange(2,4,1,31).getValues();
    console.log(day_of_week[0][1])
    for(i=0; i<31; i++){
        var day = day_of_week[0][i];
        
        if(day == "土"){
            ss.getRange(1, i+4, 2, 1).setBackground("blue").setFontColor("white");
        } else if(day == "日"){
            ss.getRange(1, i+4, 2, 1).setBackground("red").setFontColor("white");
        }
    }

    // ３行目から6行目、8行目のデータを削除
    ss.getRange(3,4,4,31).clearContent();
    ss.getRange(8,4,1,31).clearContent();
}

function onOpen(){
  const customMenu = SpreadsheetApp.getUi();
  customMenu.createMenu('初期化')
      .addItem('今のシートを初期化する', 'sheet_init') 
      .addToUi()
}
```

今現在開いているシートに対して、

日付行の色をリセット
データ行（3行目〜6行目、8行目）で手入力している部分を削除
土曜もしくは日曜だった場合には色を変更
といった感じで動作させています。

今回のプログラムだと、列の最大（日付）が31なので、増えることを考えなくて良いのが楽ちんでした。

プログラムの初回実行をする際はセキュリティ通知があるのでご注意くださいね。
【AWS認定合格記】AWS ソリューションアーキテクトアソシエイト(SAA-C03)

## はじめに
:::note warn
受験は今から1年以上も前のことになりますが、当時の勉強方法などの備忘録を記載しています。
:::


軽く自己紹介すると、、
◆学部卒(非情報系)
◆新卒でSIerに入社し、3年目。
◆取得資格
| 資格名 | 取得日 |
|:-----------|:-----------|
| 基本情報技術者 | 2021年11月  |
| AWS クラウドプラクティショナー | 2023年2月 |
| AWS ソリューションアーキテクトアソシエイト | 2023年7月 |
| AWS ソリューションアーキテクトプロフェッショナル | 2024年3月 |
| AWS デベロッパーアソシエイト | 2024年3月 |
| AWS sysOps Administrator アソシエイト | 2024年4月 |


:::note info
sysOpsAdministratorアソシエイトを取得するまでは、業務ではAWSに携わったことはありませんでした。
:::



## 勉強方法
使用した問題集は、**Udmeyのみ**でした。

 https://www.udemy.com/course/aws-knan/?couponCode=JPLETSLEARNNOW

個人的なUdemyの使い方は以下。
　①まずは、問題に目を通してみる。
　②分からないワードを調べる。
　③答えを見てなぜその答えなのか、解説を読む。分からないところは調べる。
　④全ての問題で①〜③を行う。
　⑤実際に答えを見ずに解けるか確認する。


:::note info
SAAの前に受けたCLFと比べると、問題の文章が少し長くなり、難易度も高いのが問題集を解きながら感じていました。
:::


## 勉強期間
合格までに要した期間は**約3週間**。

平日：約3時間〜4時間
休日：約7時間~9時間

ざっくりの計算で**約100時間ほど**でした。



## 試験当日

| 時間 | 流れ |
|:-----------|:-----------|
| 13:00 | 試験開始|
| 15:00 | 試験終了|
| 18:17 | 合格通知メール届く|　


試験は120分間ですが、1時間ほどで解き終わりました。

試験終了後の感覚としては、CLF同様Udemyで解いた問題と似た問題が多く(半分以上)、少し手応えはありました。
午後の受験だったため、また翌朝に結果が出るのかな〜と思っていたら、試験終了後3時間で結果が届き驚きました。

https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/

## モチベーションの保ち方
当時、入社2年目となり、SEとしてこれができます！という強みが欲しいと思っていました。
CLF受験の時にあった、社内でAWSの資格をみんなで取ろう！みたいな運動がまだ続いており、その流れせっかくCLF取ったし、もっと学んでみたい！と思い、みんなと一緒に勉強して取りました。
**周りが勉強しているという刺激に加えて、入社2年目でSEとしての自信が欲しいという想い**がモチベーションになっていたと思います。

## 受験〜合格しての所感
### 2個目のAWS資格取得。嬉しい！もう少し頑張ってみようかな〜

SAAに合格してから、もっとAWSを勉強したいという気持ちが強くなりました。
(この後PJが多忙すぎて、約半年AWSについて考える余裕がなくなることをこの時は知りませんでした、、)

:::note info
クラウドプラクティショナー同様、当日もひっかけ問題はなかったので、Udemy等で勉強してれば基本的には合格できると感じました。
:::
ポートフォワーディングが分からない

# 自分のPCからWindowsサーバーへ、ポートフォワーディングを使用してRDP接続をしたい。

#### 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877114/3657b796-334b-e996-a5eb-d99aa82df5a5.png)

#### 環境
・自分のWindowsPC１台
・VMware仮想マシン1踏み台サーバー(CentOS)
・VMware仮想マシン2WindowsServer

#### 実施したこと
・下記コマンドをコマンドプロンプト上で実行
~~~
ssh -L 13389:192.168.1.2:3389 admin@10.0.0.2
~~~

・リモートデスクトップ接続でlocalhost:13389を実行し、ユーザー名パスワードを入力後RDP成功

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877114/bf88c0a0-53c5-6f68-bb29-9c008b16c323.png)


#### 知りたいこと
・通信をする際、自分のPCはどこの情報をもとにポートを通るの？
・通信をする際、ポートを通るタイミングっていつ？
・どんな順番で通信している？
Python基礎（除算、__doc__、argparse、random）

## 自己紹介
- Python独学歴2年目です（実務ではほぼ使っておりません）
- 普段の業務
  - SQL
  - PL/SQL
  - BIツール
- Pythonを選んだ理由
  - とある理由でWeb上からデータを取得したかった
  - 比較的簡単
  - 名前がかっこいい
## 本題
とりあえず資格いっとくかという勢いでPython基礎認定試験の勉強始めました(2024/09/02)
なんですが、2~3割くらい明確な答えがわからず正解or不正解しているのがあるので復習

ちゃちゃっと行きます。

***
### 徐算について
- Pythonでは「/」を使った除算は浮動小数点になる
```python
addition = 2 + 5
subtraction = 7 - 5
multiplication = 2 * 5
division = 10 / 2
division2 = 10 // 2 # 「//」を使う

print(addition)
print(subtraction)
print(multiplication)
print(division)
print(division2)

# 結果
>>> 7
>>> 2
>>> 10
>>> 5.0 # 結果は整数だが、5.0となる
>>> 5
```

***
### ドキュメンテーションコメントの出力
- __doc__属性に文字列として格納されてる
  
```Python
def hoge():
    '''
    これはテストです。

    Arguments:
        None

    Return:
        None
    '''
    print("Hello!!")

print(hoge.__doc__) # 必要に応じてtype(hoge.__doc__)でもいいかもね

>>> これはテストです。
>>> Arguments:
>>>     None
>>> Return:
        None

# こんなのもある
print(help(hoge))

>>> Help on function hoge in module __main__:
>>> 
>>> hoge()
>>> これはテストです。
>>>
>>> Arguments:
>>>    None
>>> Return:
>>>     None
```

***
### コマンドライン引数(argparseモジュール)
- sys.argvよりもいい感じのCLIを作成できる
```parse.py
import argparse

parser = argparse.ArgumentParser() # インスタンス生成
parser.add_argument("arg1")
parser.add_argument("arg2", nargs="+") # こちらは引数を1以上必須とします
args = parser.parse_args()
print(args)
```
- 下記の様に実行
```powershell
python parse.py 果物 りんご 梨

# 結果
Namespace(arg1='果物', arg2=['りんご', '梨'])
```
- 引数を正しく与えないパターン
```powershell
python parse.py

# 結果
usage: parse.py [-h] arg1 arg2 [arg2 ...]
parse.py: error: the following arguments are required: arg1, arg2
```
- ほかにも色々できそうなので今度CLIツール作成する時に使ってみたい

***
### randomモジュール
- random関数
```python
import random

print(random.random())  # 0以上1未満のランダムなfloatを返す
# 例）0.23441577915211131
```

- choice関数
```python
import random

print(random.choice(range(10)))  # 引数に与えられた中から1つ文字列を返す
# 例）2
```

- uniform関数
```python
import random

print(random.uniform(0, 10))  # 0以上10以下のfloatを返す
# 例）6.630403607319101
```

- randint関数
```python
import random

print(random.randint(0, 10))  # 0以上10以下のintを返す
# 例）7
```

- sample関数
```python
import random

# random.sample(a, b)  aからb個重複なしで抽出

print(random.sample(range(0, 10), 3))
# 例）[2, 9, 4]
```

- randrange関数
```python
import random

# randrange(a, [b], [c])  aからb未満のステップcでintを返す

print(random.randrange(0, 10, 2))  # 0から10未満の0を含めた2の倍数を返す
# 8
```
【豆知識】CSVファイルインポートを少し学ぶ

# はじめに
選択形式のフォームを用意して、都道府県を選べるようにするなら`db/seeds.rb`に必要事項入力すればいいのですが、私はもっと沢山のデータを選択形式で行いたかったので、どうすればいいか調べていました。
何とかcsvファイルは作成したもののいざ、インポートする段階になった時`rake`と`seed`の2パターンあることを知りました。

なので、今回はインポートの方法でrakeとseedでの違い、それぞれの特徴、メリットデメリット、などをアウトプットしたいと思います

## 環境
- Windows, WSL
- Docker
- Ruby 3.2.3
- Rails 7.1.3



## それぞれの特徴など

### **1. Rakeタスク**
### **特徴**
- Rakeタスクは、特定の処理を行うためのスクリプトを作成できる
- `lib/tasks`フォルダにRubyファイルを作成して、その中にタスクを書く

### **メリット**
- 汎用性が高い：特定の処理を何度でも実行できる。
- 開発環境や本番環境に影響を与えず、必要な時だけ実行できる。
- データのインポート処理を分けることで、初期データと運用データを明確に管理できる。

### **デメリット**

- 手動で実行する必要がある（`rails import:csv`のように）。
- 初心者には少し複雑に感じる場合がある。

### **2. seeds.rb**
### **特徴**

- アプリケーションの初期データを設定するためのファイル。
- `db/seeds.rb`に初期データの作成コードを書く。

### **メリット**

- 簡単にデータベースを初期化できる：`rails db:seed`で実行できる。
- 新しいプロジェクトや環境を立ち上げる際に、簡単にデータを投入できる。

### **デメリット**

- 本番環境でも実行されるため、意図しないデータの挿入があるかもしれない。
- 初期データが多くなると管理が難しくなることがある。

## **Rakeタスクの実行環境について**

RakeタスクでCSVをインポートした場合、開発環境と本番環境の両方で実行できます。実行する環境によって影響が出るかもしれないから、注意が必要です。特に、本番環境ではデータの整合性を保つために、実行する内容を確認することが重要になります。

## **CSVを何度も修正する場合**
CSVを何度も修正する可能性があるなら、Rakeタスクを使った方がおすすめのようです。理由としては次のようなことが挙げられます。

- Rakeタスクは実行するたびにデータをインポートできるから、修正後のCSVを簡単に再実行できる。
- `seeds.rb`は基本的に初期データを設定するためのものだから、何度も実行するのは向かない場合がある。


# さいごに
詳しいインポートするためのコードや導入手順については割愛。
RakeとSeed2パターンあることを今回初めて知ることができてよかったです。
この記事が何か参考になれば幸いです。
M1/M2 macでPython−MIPを動かすには？（uv版）

この記事は、次の2記事の続編です。M1/M2 macでPython−MIPを動かす方法を説明します。

https://qiita.com/SaitoTsutomu/items/fbc33299e1906a238f53

https://qiita.com/SaitoTsutomu/items/aabb94db3f20cce3dc82

Python−MIPに付属するソルバーCBCは、x86_64用であるため、そのままでは動きません。
また、Python-MIPはCFFIでソルバーを動かすため、Python自身がx86_64上で動く必要があります。

ここでは、uvを使って動かす方法を紹介します。

https://github.com/astral-sh/uv

## 準備

Rosetta2とuvが必要です。
Rosetta2を有効にするには、一度だけ次のようにします。

```zsh
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
```

macOSやLinuxでuvをインストールするには、次のようにします。

```zsh
curl -LsSf https://astral.sh/uv/install.sh | sh
```

さらに、次のようにコマンドの補完設定用のファイルを作成します。
※ zshを想定しています。

```zsh
~/.cargo/bin/uv generate-shell-completion zsh > ~/.uv_completion.sh
```

uvを使うために次を`~/.zprofile`に追加し、`source ~/.zprofile`としてください。

```zsh
source $HOME/.cargo/env
source $HOME/.uv_completion.sh
```

## X86_64用Pythonのインストール

次のようにすると、インストール可能なPythonのバージョンを確認できます。

```zsh
uv python list --all-platforms
```

`macos-x86_64`を含むものを探してください。今回は、次のように`cpython-3.12.5-macos-x86_64-none`を使います。

```zsh
uv python install cpython-3.12.5-macos-x86_64-none
```

## 仮想環境の構築

次のようにして、新しいプロジェクトを作成して仮想環境を構築しましょう。

```zsh
uv init mip-sample
cd mip-sample
uv python pin cpython-3.12.5-macos-x86_64-none
```

`.python-version`というファイルが作成され、`pin`で指定したバージョンが入ります。

※ `warning: No interpreter found for cpython-3.12.5-macos-x86_64-none in managed installations or system path`と出ますが、使えるようです。

次のようにして、Python-MIPをインストールします。

```zsh
uv add mip
```

## サンプルの実行

カレントディレクトリの`hello.py`を次のように修正してみましょう。

```python
from mip import Model, maximize, minimize, xsum

m = Model()  # 数理モデル
# 変数
x = m.add_var("x")
y = m.add_var("y")
# 目的関数
m.objective = maximize(100 * x + 100 * y)
# 制約条件
m += x + 2 * y <= 16  # 材料Aの上限
m += 3 * x + y <= 18  # 材料Bの上限
m.optimize()  # ソルバーの実行
print(x.x, y.x)  # 4.0 6.0
```

次を実行してCBCが動くことを確認できます。

```zsh
uv run hello.py
```

uvの詳細については、ドキュメントを参考にしてください。

https://docs.astral.sh/uv/

## まとめ

* arm64アーキテクチャでも、uvを使うことで`x86_64`のPythonやパッケージをインストールして実行できる

以上
就活つらい。せめてマイページにログインするのを自動化したい。

# 概要 #
### 就活つらい。 ###
就活を始めると企業のサイトに登録しなきゃですが、複数の企業に登録してたら全部を確認するのが結構大変。というか面倒くさい。
なるべく楽に生きたいので、Seleniumで企業のマイページにログインしていきます。
就活、マジでやばいです。夏のインターンどこも行ってない。何とかなれ。

## 志望企業といえど、マイページに行くの面倒ですよね ##
私はめっちゃ面倒です。
というか研究と両立できない。勘弁してください。

# Seleniumで全部できるやん #
Excelに必要な情報入れれば、あとはSeleniumで全部操作できるじゃんと思いました。
以下がそのExcelです。(見本)
![ekuseru.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633825/4302aa4b-f02e-b364-629f-2a58992ec681.jpeg)
マイページにログインするサイトのURLと、自分のID、パスワード、IDとパスワードを入力するテキストボックスのXpathと、ログインボタンのXpathをExcelに貯めます。

 Xpathを調べるのがちょっと面倒臭いですが、一度だけなので頑張って取ってくる。
for文で回そうとしたので、xpathがいいかなって思いました。

あと確実に、パスワードを貯めるとか何となくセキュリティ的によくないと思うので、そのへん許せる人だけやってね。

### #環境 ###
エディタ：Visual Studio Code
Python 3.12.2
selenium 4.24.0
pandas 2.2.2（Excelからデータを持ってくるため）

Seleniumのwebdriverはこれを見てやりました。（多分……）
https://qiita.com/sagami1991/items/fdcc454e4ffe70a07507

### #コード ###
詳しくは知らないのですが、ウェブ操作自動化系は相手のサーバ側に負荷がかかってしまう可能性があるので、使い方には気を付けましょう。
そこは自己責任ということで…

```python:login.py
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import os
import signal
import pandas as pd

# Excelファイルは同じ階層に置いてるので
df = pd.read_excel('job.xlsx', sheet_name='id')

url = df.iloc[:,1].tolist()
id = df.iloc[:,2].tolist()
pwd = df.iloc[:,3].tolist()
id_box = df.iloc[:,4].tolist()
pwd_box = df.iloc[:,5].tolist()
loginbtn = df.iloc[:,6].tolist()

browser = webdriver.Chrome()

def login(num):
    browser.get(url[num])
    browser.implicitly_wait(5)
    id_target = browser.find_element(By.XPATH, id_box[num])
    id_target.send_keys(id[num])
    time.sleep(0.2) # 負荷はかけたくないよという気持ちの表れ。どのくらい待てばいいか正直分かってない。ごめんなさい。
    pwd_target = browser.find_element(By.XPATH, pwd_box[num])
    pwd_target.send_keys(pwd[num])
    time.sleep(0.2)
    btn = browser.find_element(By.XPATH, loginbtn[num])
    btn.click()

try:
    for i in range(len(url)):
        login(i)
        if i<(len(url)-1):
            #新規タブを作成して、そのタブをアクティブにする。
            browser.switch_to.new_window('tab') 

finally:
    # プログラム終了後にも、ページは開いたまま
    os.kill(browser.service.process.pid,signal.SIGTERM)
```
プログラムの良し悪しはおいておいて、実行したら全部のサイトでログインができます。

# 終わり #
初めてQiitaに投稿しますが、「この程度のこと、書き起こす必要なくないか…？」と思いながら後半書きました。ヤバいところがあれば教えてください…
Placehold: イメージプレースホルダーサービス

## はじめに
Placeholdは、必要な画像を簡単に、しかも無料で生成できるサービスです。画像のサイズ、フォーマット、色、テキストを自由にカスタマイズできるため、さまざまなデザインニーズに対応します。

## Placeholdの使い方

Placeholdは、URLを指定するだけで、画像のサイズ、フォーマット、色、テキストを設定し、プレースホルダー画像を生成できます。

## 主な機能と使用方法

### 1. サイズ指定

画像のサイズは、URLに width x height 形式で指定します：

- 長方形の画像: https://placehold.co/600x400
- 正方形の画像: https://placehold.co/400

### 2. 画像フォーマット

デフォルトはSVGですが、PNG、JPEG、GIF、WebPフォーマットもサポートしています：

- PNGフォーマット: https://placehold.co/600x400.png

### 3. カラーのカスタマイズ

背景色とテキスト色は、HEX値またはCSSカラー名で指定できます：

- HEXカラー: https://placehold.co/600x400/000000/FFF
- CSSカラー名: https://placehold.co/600x400/orange/white

### 4. テキスト追加

画像に表示するテキストも簡単にカスタマイズ可能です：

- 基本テキスト: https://placehold.co/600x400?text=Hello+World
- マルチラインテキスト: https://placehold.co/600x400?text=Hello\nWorld

### 5. フォントのカスタマイズ

テキストのフォントを指定することができます：

- Robotoフォント: https://placehold.co/600x400?font=roboto
- 利用可能なフォント: Lato, Lora, Montserrat, Open Sans, Oswald, Playfair Display, PT Sans, Raleway, Roboto, Source Sans Pro

### 6. レティナ画像

高解像度ディスプレイ用に、サイズの後ろに @2x または @3x を追加すると、レティナ画像を生成できます：

- 2xレティナ画像: https://placehold.co/600x400@2x.png

## 結論

Placeholdは、素早く効率的にプレースホルダー画像を生成するツールで、さまざまなプロジェクトで役立ちます。ぜひPlaceholdを活用して、ウェブデザインや開発作業をよりスムーズに進めましょう！
[HR Management] 

# 一覧
|名称|詳細|
|:--|:--|
|コンティジェンシ理論|状況によってリーダーシップのスタイルも変化すべきとする理論|
|SL理論|リーダーシップの有効性は`部下の習熟度`に依存するとする理論<br>``タスク志向``と``人間関係志向``の強弱で分類|
|PM理論|リーダーシップの有効性は`P機能（Performance Function：目標達成機能）`と`M機能（Maintenance Function：集団維持機能）`に依存するとする理論|


# 参考リンク
- [R3S75_SL](https://www.ap-siken.com/kakomon/03_haru/q75.html)
- [R3A74_SL](https://www.ap-siken.com/kakomon/03_aki/q74.html)
- [R4S75_PM](https://www.ap-siken.com/kakomon/04_haru/q75.html)
メラビアンの法則を超えて：心を動かすコミュニケーションの真髄

# メラビアンの法則を超えて：心を動かすコミュニケーションの真髄

![title](https://raw.githubusercontent.com/legitwhiz/legitwhiz.github.io/master/technology_memo/images/1000008281.jpg)


## メラビアンの法則とは

コミュニケーションスキルを語るとき、よく耳にする『メラビアンの法則』。

人間の印象は、『メラビアンの法則』では以下のように定義し、その割合を実際の人で検証し算出した結果だそうです。

・視覚情報(見た目、しぐさ、表情、視線)55%

・聴覚情報(声の質や大きさ、話す速さ、口調)38%

・言語情報(言葉そのものの意味、会話の内容)7%

割合を見ると大半が『視覚情報』なんですね。

もちろん、私の経験則から言っても『メラビアンの法則』を意識したほうがいいのは事実です。

## メラビアンの法則より大事なこと

ですが、上記割合を考慮したうえで営業や提案、面接などをし、相手を論破したとしても、腑に落ちてなければ相手は、行動には至らないのが現実です。

作成した資料や相手に伝えた言葉には、内容に『想いの本気度』が込められているか？

不格好でも言葉が稚拙でも、そこに『情熱』や『意欲』があれば、相手の心を動かし行動に移させることができる大事なことではないでしょうか？
Enter押下と日本語IMEの不愉快な関係を解消する

この世界は「Enter」を押して確定するテキストフィールドで溢れています。そしてその多くが、日本語IMEの部分確定のために押し下げられたEnterを誤認して、入力中のテキストを確定してしまいます。
今日私は、Reactで作っているアプリで同じ目に遭い、（GPTに聞いて）解消することができました。

特に難しいことも新しいこともしていません。Composing中はEnterを無視しているだけです。

```tsx
import React, { useState } from "react";
const [isComposing, setIsComposing] = React.useState(false);

const TreeView: React.FC<TreeViewProps> = ({
  const handleKeyDown = (event: {
    stopPropagation: () => void;
    key: string;
  }) => {
    event.stopPropagation();
    if (event.key === "Enter") {
      // If IME is acrive, Enther must be ignored
      if (!isComposing) {
        if (!isEditing) {
          // Editing
          setIsEditing(true);
        } else {
          // Fixing
          handleBlur();
        }
      }
    }
  };

  const handleCompositionStart = () => {
    setIsComposing(true);
  };

  const handleCompositionEnd = () => {
    setIsComposing(false);
  };
  return (
    <input
    type="text"
    value={editValue}
    onChange={handleChange}
    onKeyDown={handleKeyDown}
    onCompositionStart={handleCompositionStart}
    onCompositionEnd={handleCompositionEnd}
    onBlur={handleBlur}
    className="item-name-input"
    />
  )
```

おそらく、このエントリーをご覧の皆さんの多くはご存知のことでしょう。
私がこのエントリーを書いた理由は、IMEに馴染みのないエンジニアが書いたコードへの改善要求のためです。

Enter押下で確定するコードを書いているときに、「こうやってOnCompositeで処理してください」とお願いすると幸せになれるかもしれません。
Azure 環境でウェブアプリを作る際のソリューションの選び方メモ

ASP.NET / Azureをメインに活用する際にどのようなソリューを選ぶか、簡単にまとめてみました。なんとなくですが、よく使っている順になっています。


# ウェブサイト・アプリをホストするなら Web Apps

とりあえず、クラウド上でウェブアプリをホスティングするならこれ。ウェブアプリでもAPIでもとりあえずここに構築します。

https://azure.microsoft.com/ja-jp/products/app-service/web

# ログイン系はASP.NET Core Identity x Azure SQL Database

ASP.NET Core Identityはこちら

https://github.com/dotnet/aspnetcore/tree/main/src/Identity

Azure SQL Databaseはこちら、安価でスタートできるが、ハイスペックにしようと思うと高価になるので設計が重要となってくる。

https://azure.microsoft.com/ja-jp/products/azure-sql/database/

# とりあえずこれもセットで使う、色々保存する先は基本Azure Tableで

Azure Tableはマスターするべき安価でありながら、スケールすることが可能。基本マスターデーターはここに持つべき。

https://azure.microsoft.com/ja-jp/products/storage/tables/

# ソースコードの管理、タスクの管理、テストの管理、ドキュメントの管理、CIはAzure Dev Ops または Github

Azure Dev Opsはこちら
https://azure.microsoft.com/ja-jp/products/devops

過去にまとめた記事はこちら

https://qiita.com/syantien/items/5889b5dd2c2030999975

https://qiita.com/syantien/items/856385355cf81d8e7106

Githubはこちら
https://github.co.jp/


# 様々なタスクをこなすなら Azure Functions

トリガーベースでタスクを処理するならAzure Functionsで

https://azure.microsoft.com/ja-jp/products/functions/

# 頻繁な読みで少なめな更新であればAzure Cache For Redis

Azure Cache For Redis
https://azure.microsoft.com/ja-jp/products/cache/

# 大量のデータをテキスト検索する場合はAzure AI Search

テキスト検索もそうですが、Facetなど高度な検索をしたい場合はこちら

https://azure.microsoft.com/ja-jp/products/ai-services/ai-search

# 大量のリクエストをQue処理するなら Service Bus

Service Busはこちら

https://azure.microsoft.com/ja-jp/products/service-bus/

以上です、また更新していきます。


# 仲間募集中

Azure詳しい人と一緒に仕事したいです。よろしくお願いします。

https://receiptroller.com

# 店舗の方も絶賛募集中

電子レシート導入した店舗様も募集中

https://business.receiptroller.com/ja
JavascriptでWebサイトを録画してみる

# はじめに
クライアントからWebサイトに録画機能を追加したいというご要望をいただきましたので、以下のサイトを参考にして最低限のサンプルコードを作成し検証しました。
[【分かりやすく解説】Javascriptで画面録画をする方法](https://www.crunchtimer.jp/blog/18169)

# サンプルコード要件
・Windows11 + Chromeで動作すること
・録画は映像のみで音声は不要
・「Shift＋R」で録画開始、「Shift＋E」で録画終了および録画ファイル保存

# サンプルコード
動きがわかりやすいように「video」タグのみ表示させています。

~~~php:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
</head>

<body>
    <video style="width:1024px;" src="https://cdn.pixabay.com/video/2023/10/22/186115-877653483_large.mp4" autoplay muted playsinline loop></video>
    <script src="app.js"></script>
</body>

</html>
~~~

~~~php:app.js
let mediaRecorder;
const recordedBlobs = [];
let isRec = false;
const type = 'webm';

async function startRecording() {
  const screenStream = await navigator.mediaDevices.getDisplayMedia({ video: true });
  const options = { mimeType: 'video/' + type };

  mediaRecorder = new MediaRecorder(screenStream, options);
  mediaRecorder.ondataavailable = (event) => {
    if (event.data && event.data.size > 0) {
      // 録画データが格納される
      recordedBlobs.push(event.data);
    }
  };

  mediaRecorder.start();
  console.log('録画開始');
}

function stopRecording() {
  mediaRecorder.stop();
  console.log('録画停止');
  mediaRecorder.onstop = () => {
    saveRecording();
  };
}

function saveRecording() {
  console.log('録画保存');
  const blob = new Blob(recordedBlobs, { type: 'video/' + type });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.style.display = 'none';
  a.href = url;
  a.download = 'WebRec.' + type;
  document.body.appendChild(a);
  a.click();
  setTimeout(() => {
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }, 100);
}

document.addEventListener('keypress', (event) => {
  if (event.shiftKey) {
    if( event.key === 'R' ) {
      if (isRec === false) {
        startRecording();
        isRec = true;
      }
    }
    if( event.key === 'E' ) {
      if (isRec === true) {
        stopRecording();
        isRec = false;
      }
    }
  }
});
~~~

# 実行結果
「Shift＋R」で対象画面を選択すると録画が開始されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/16aec8e9-e001-0ddf-0f7a-a3974266d532.png)

「Shift＋E」で録画を終了し、ダウンロードフォルダに録画ファイル(webm)が保存されます。
録画時のサイト表示画角がフルHD、4Kサイズ共に録画ファイルをWindowsメディアプレイヤーで再生可能でした。

# mp4で録画できないの？
2024年6月に公開された[Chrome 126](https://developer.chrome.com/release-notes/126?hl=ja)でMediaRecorder向けのMP4コンテナがサポートされましたので、mp4の録画も試してみます。
なお、検証時のChromeバージョンは 128.0.6613.120 です。
 
「app.js」内の以下の部分を「webm」から「mp4」に変更するとmp4で保存されます。
~~~
const type = 'webm';
~~~

検証したところ、録画時のサイト表示画角がフルHDサイズの場合はWindowsメディアプレイヤーで再生できましたが、4Kサイズの時は冒頭3秒程度しか再生できませんでした。(原因不明、PCメモリは16GB)

# 最後に
今回はWindows11+Chrome最新バージョン+webm/mp4で検証しましたが、MediaRecorderのサポート状況は[MediaRecorder.isTypeSupported](https://developer.mozilla.org/ja/docs/Web/API/MediaRecorder/isTypeSupported_static)で確認できます。

サポート状況を確認するための便利なサイトがありますのでリンクを貼っておきます。
https://www.sitelint.com/lab/media-recorder-supported-mime-type/
【備忘】Fabric / Azure Data Factory パイプライン メモ

個人的メモです

## よく使うパイプライン式、変数など


### パイプラインパラメータ/変数設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/8cae22a8-ef78-f954-282f-6c476c75bd4c.png)


| パラメータ | 名称 | 値の例や説明 |
|:-:|:-:|:-:|
|source_system_type   | ソースシステムの分類  | transactional / master_and_reference (統合マスター管理システムなど)/ log / telemetry  |
|source_system_name   | ソースシステム名  | - |
|entity_name   |対象エンティティ名   | スキーマ名_テーブルのように検討 |
|version   |ファイルのバージョン   | version_{メジャーバージョン}.{マイナーバージョン}として、マイナーバージョンはメジャーバージョンデータに対して加工が必要となった場合に、加工結果を配置する。メジャーバージョン0.xを初期移行データとして保管する   |
|load_type   | 連携種別  | delta (差分連携) / full (全件連携)  |
|partition_type   | パーティション種別  | hive(※推奨値　列名=値の形式にフォルダ名が管理されるhiveパーティション形式で保存する場合に使用）/customer(それ以外のディレクトリ形式で保存する場合)|
|audit__run_at   | ジョブ実行タイムスタンプ  | audit__run_at_id , audit__run_date の基となる  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/9ed58a4d-ff6c-dffb-9e8b-8d55280b731b.png)


| 変数 | 名称 | 値の例や説明 |
|:-:|:-:|:-:|
|audit__run_date   | ジョブ実行日| audit__run_atから導出。audit__run_date={yyyy-MM-dd} として、hiveパーティションが機能するように扱う |
|audit__run_at_id   | ジョブ実行タイムスタンプ(yyyyMMddhhmmss形式)   | audit__run_atから導出。audit__run_at={yyyyMMddHHmmss}として、 hiveパーティションが機能するように扱う |


### ファイルの配置先

```

@concat(
    'landing/',
    pipeline().parameters.source_system_type,'/',
    pipeline().parameters.source_system_name,'/',
    pipeline().parameters.entity_name,'/',
    pipeline().parameters.version,'/',
    pipeline().parameters.load_type,'/',
    pipeline().parameters.partition_type,'/',
    'audit__run_date=',variables('audit__run_date'),'/',
    'audit__run_a_id=',variables('audit__run_at_id')
)

```

### アクティビティの実行時間を日本時間、yyyyMMddhhmmss形式で記録

```

 formatDateTime(convertFromUtc(utcnow(),'Tokyo Standard Time'),'yyyyMMddHHmmss')

```

audit__run_at 導出の場合

```

formatDateTime(convertFromUtc(pipeline().parameters.audit__run_at,'Tokyo Standard Time'),'yyyyMMddHHmmss')

```

### アクティビティの実行日を日本時間で記録

```

formatDateTime(convertFromUtc(utcnow(),'Tokyo Standard Time'),'yyyy-MM-dd')

```

audit__run_at 導出の場合

```

formatDateTime(convertFromUtc(pipeline().parameters.audit__run_at,'Tokyo Standard Time'),'yyyy-MM-dd')

```




## ファイル有無チェック

https://azurelib.com/how-to-check-if-file-exist-in-azure-data-factory-adf/#:~:text=How%20To%20Check%20IF%20File%20Exist%20In%20Azure,decisions%20based%20on%20the%20result%20of%20GetMetaData%20Activity.

## ファイル並び替え

アクティビティには今はないのでストアドで。

https://stackoverflow.com/questions/58054800/how-does-get-metadata-order-sort-its-output

### 更新日時や、ファイル名取込で対応も

https://qiita.com/ryoma-nagata/items/b5cf6a16ef06b41a5404
2つの画像を合成させる方法

## 前置き
画像に署名（名前など）を入れたいとき、今までは画像編集ソフトを使用して行っていました。
しかし、画像に名前を入れるためだけのために画像編集ソフトを立ち上げるのが面倒だったので、簡単に名前を入れられるような仕組みが無いか考えました。

## だったら2つの画像を合成すればいいのでは
そこで、インプット用の画像と署名用の画像を用意して、2つの画像を合成するプログラムを作成しました。

### ざっくりとした仕様
input画像フォルダの中にあるpngファイルを抽出。
抽出したファイルに署名用ファイルを合成。

画像を操作するライブラリとしてPillowを採用。
インストールしていない場合は以下のコマンドでインストールしてください。

```
pip install Pillow
```

jsonファイルに以下を記載
- 署名用画像を張り付け位置（X座標、Y座標）
- 入力画像が格納されているパス
- 署名用画像のパス
- 合成した画像を出力する場所のパス

```json:settings.json（記載例）
{
    "X": 10,
    "Y": 20,
    "inputDir": "C:\\sample\\input\\",
    "outputDir": "C:\\sampley\\output\\",
    "overlay" : "C:\\Usample\\signature.png"
}
```

### ソースコード

```python:ImageOverlay.py
from PIL import Image
import json
import glob
import os

# 設定ファイル(.json)を読み込む関数
def load_settings(settings_path):
    # エンコードを指定してあげないと文字化けする可能性がある。
    with open(settings_path, 'r', encoding='utf-8') as file:
        settings = json.load(file)
    return settings

# 画像を合成する
def combine_images(main_image_path, overlay_image_path, output_image_path, settings):
    # メイン画像とサブ画像を読み込む
    main_image = Image.open(main_image_path)
    overlay_image = Image.open(overlay_image_path)

    # サブ画像を指定位置に重ねる
    main_image.paste(overlay_image, (settings['X'], settings['Y']), overlay_image)

    if os.path.exists(output_image_path):
        os.remove(output_image_path)

    # 合成結果を保存
    main_image.save(output_image_path)

def main():
    # 実行したPyファイルのパスを取得する。
    script_file_path = os.path.abspath(__file__)
    dir_path = os.path.dirname(script_file_path)

    # 設定ファイルのパス
    settings_path = dir_path + '\\settings.json'

    print('settigs_path : ' + settings_path)

    # 設定ファイルを読み込む
    settings = load_settings(settings_path)

    main_image_path = settings['inputDir'] + '*.png'
    files = glob.glob(main_image_path)

    # 出力先のパス
    output_path = settings['outputDir']

    print('output_path : ' + output_path)

    # オーバーレイ
    overlay_image_path = settings['overlay']
    print('overlay_image_path : ' + overlay_image_path)

    for file in files:
        # ファイルパスからファイル名のみを取得
        filename = os.path.basename(file)

        output_image_path = output_path + filename

        print('1:'+ output_image_path)
        # 画像を合成
        combine_images(file, overlay_image_path, output_image_path, settings)

if __name__ == "__main__":
    main()
```

これで、画像に名前を入れるのがかなり楽になりました。
Elixirで「メロディ」を鳴らす

Elixirで「ドレミファソラシド」を鳴らすの続編です

https://qiita.com/t-yamanashi/items/a784a774a5c25386abce

# 前提条件
- OS Ubuntu 22.04

# 仕様
- 前回のElixirで「ドレミファソラシド」を鳴らすの仕様を継承する
- 4音符/8音符/16音符の概念を追加

# ソースを書く

```elixir:lib/sox.ex
defmodule Sox do
  @a4_frequency 440
  @a4_note_no 69
  @bpm 180

  @moduledoc """
  Documentation for `Sox`.
  """

  @doc """
  Hello world.

  ## Examples

      iex> Sox.hello()
      :ok

  """
  def hello do
    note1 = [
      {78, 8},
      {77, 16},
      {0, 16},
      {73, 16},
      {0, 16},
      {0, 8},
      {78, 16},
      {0, 16},
      {77, 16},
      {73, 8},
      {0, 16},
      {0, 8}
    ]

    note2 = [{75, 16}, {75, 16}, {0, 16}, {75, 16}, {0, 16}, {75, 8}, {0, 16}]
    note3 = note_shift(note2, -4)
    note4 = note_shift(note2, 3)

    note1
    |> Enum.concat(note1)
    |> Enum.concat(note2)
    |> Enum.concat(note3)
    |> Enum.concat(note2)
    |> Enum.concat(note4)
    |> List.duplicate(2)
    |> List.flatten()
    |> Enum.each(&play(&1))

    :ok
  end

  def note_shift({0, time}, _), do: {0, time}
  def note_shift({note, time}, shift), do: {note + shift, time}

  def note_shift(notes, shift) when is_list(notes) do
    notes
    |> Enum.map(&note_shift(&1, shift))
  end

  def note_no_to_frequency(@a4_note_no), do: @a4_frequency

  def note_no_to_frequency(note) when note < @a4_note_no,
    do: @a4_frequency / :math.pow(2, 1 / 12 * (@a4_note_no - note))

  def note_no_to_frequency(note) when note > @a4_note_no,
    do: @a4_frequency * :math.pow(2, 1 / 12 * (note - @a4_note_no))

  def play({note, time}), do: play(note, time)

  def play(0, time) do
    sec = get_sec(time)
    play_cmd(0, sec)
  end

  def play(note, time) do
    sec = get_sec(time)

    note_no_to_frequency(note)
    |> play_cmd(sec)
  end

  def play_cmd(frequency, time), do: System.cmd("play", ~w"-n synth #{time} sin #{frequency}")

  def get_sec(1), do: get_sec(4) * 4
  def get_sec(2), do: get_sec(4) * 2
  def get_sec(4), do: 60 / @bpm
  def get_sec(8), do: get_sec(4) / 2
  def get_sec(16), do: get_sec(4) / 4
end
```
# 実行

```sh
$ mix test
```

<iframe width="1280" height="720" src="https://www.youtube.com/embed/G0caswl36Uk" title="Elixirで「メロディ」を鳴らす" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# ソース(github)

https://github.com/ymn-t-yamanashi/sox/releases/tag/v0.03