OmniAICreator/Qiita-1.07M huggingface dataset:
【Kotlin】拡張関数をざっくり理解する

KotlinとJavaのサンプルコードから`拡張関数`をざっくり理解する

## 拡張関数とは

既存のクラスに対して新しいメソッドを追加できる機能

## それって何が良いの？

:::note info
「**既存**」のクラスに対して新しいメソッドを追加できる
:::

つまり、IntegerやStringなど、標準ライブラリに含まれるクラスに対して、メソッドを追加することが可能となる

## Javaの場合

Javaには拡張関数が存在しないため、以下のように**新しいクラス**を作成し、その中に静的メソッドを定義する必要がある

```java
public class StringUtil {
    public static String capitalizeFirst(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    }
}

// 利用側
String str = "hello";
String capitalizeFirstStr = StringUtil.capitalizeFirst(str);
System.out.println(capitalizeFirstStr); // Hello
```

新しく作成した`StringUtil`クラスの`capitalizeFirst()`メソッドを利用している

## Kotlinの場合

**既存のクラス**に対して拡張関数を定義することができる

```kotlin
fun String.capitalizeFirst(): String {
    return if (isEmpty()) {
        this
    } else {
        this[0].toUpperCase() + substring(1)
    }
}

// 利用側
val str = "hello"
val capitalizeFirstStr = str.capitalizeFirst()
println(capitalizeFirstStr) // Hello
```

Stringクラスに`capitalizeFirst()`というメソッドが追加され、そのメソッドをStringクラスのインスタンスである`str`から呼び出すことが可能となる

## 注意点

1. 拡張関数の中で、元のクラスのprivateメンバにアクセスすることはできない
1. 拡張関数の中で、thisキーワードを使用して元のクラスのインスタンスにアクセスできるが、拡張関数自体にはフィールドを追加できない
1. 拡張関数が元のクラスのメソッドと同じシグネチャを持っている場合、元のクラスのメソッドが優先される

:::note info
シグネチャとは
識別子のようなもので、`メソッド名`と`引数の型と数`から構成される
:::

例えば、以下の2つのメソッドはシグネチャが異なる

```kotlin
fun add(a: Int, b: Int): Int {
    return a + b
}

fun add(a: Double, b: Double): Double {
    return a + b
}
```
2023/4/24主にITとかセキュリティの記事

AIの｢評価｣に翻弄される飲食店と物流ドライバー
｢食べログ｣掲載店舗とアマゾン配達員の嘆き(4/22)
https://toyokeizai.net/articles/-/666248

第12回 セキュリティセミナー(6/9開催)
https://news.mynavi.jp/itsearch/seminar/841

マルウェアGoldoson感染アプリ、Google Playで63本見つかる(4/22)
https://www.zaikei.co.jp/article/20230422/718767.html

【BtoC EC担当者必見】Cookie規制に打ち勝つCRM施策と、最適な不正ログイン対策！～急成長企業が実践した売れるサイトの事例公開～(4/26開催)
https://ecclab.empowershop.co.jp/archives/83002

生体認証つき｢スマート銃｣登場。誤発砲を防げるか？(4/22)
https://www.gizmodo.jp/2023/04/biofire-smart-gun.html

Windows 10 バージョン 21H2のサービス終了は6月13日！ Microsoftが再び警告(4/20)
https://forest.watch.impress.co.jp/docs/news/1495198.html

ワン・ダイニングがサイバー攻撃被害、ブランドサイトで不正なリダイレクト(4/21)
https://cybersecurity-jp.com/news/82015

マイナンバーカード推進の裏で進む法改正、個人情報利用や機能追加などに「野放図拡大」のリスク(4/22)
https://diamond.jp/articles/-/321276

根強いデジタル給与への抵抗感。メリットとデメリットのどっちが大きい？(4/22)
https://news.yahoo.co.jp/articles/ce25f92cc33d58a1ec1b31804ac01ddaa5fbc9b2?source=rss

中国が「敵」の衛星を掌握できるサイバー兵器を開発＝メディア(4/21)
https://sputniknews.jp/20230421/15754681.html
Pythonのデフォルトバージョンがずっと3.9.13だったので...

## 問題
-  pyenvでpythonのglobalバージョンを3.11にしても、変更が反映されなかった。
## 解決法
-  うんうんうなりながらいじってたら、いつぞやにインストールしたminGWのbin内にpython3.9が存在することを発見。とりあえず削除したら（大丈夫なのか？、、）、変更が反映された。
-  アプリの検索でpython3.9と打ち込んだら見つかった。もっと早くに気づいてれば...
Atcoder典型90問 001 - Yokan Party

0424進捗
# Atcoder典型90問 001 - Yokan Party
▶︎ https://atcoder.jp/contests/typical90/tasks/typical90_a

## 問題
左右の長さが 
L [cm] のようかんがあります。 
N 個の切れ目が付けられており、
左から i 番目の切れ目は左から Ai [cm] の位置にあります。

あなたは N 個の切れ目のうち K 個を選び、ようかんを K+1 個のピースに分割したいです。
そこで、以下の値を スコア とします。

K+1 個のピースのうち、最も短いものの長さ（cm 単位）
スコアが最大となるように分割する場合に得られるスコアを求めてください。
### 制約
```math
1 \leq K \leq N \leq 100000 \\
0 < A_1 < A_2 < ... < A_N < L \leq 10^9 \\
入力はすべて整数
```
## 試したこと
・全パターン数え上げは悪手じゃろ...ということでそもそも選ばない。
・動的計画法でやろうとしたがうまく組めなかった。今回の場合、「長さLの中でi+1個の切れ目の中からj+1個の切れ目を選ぶこと」を、「長さLの中でi個の切れ目の中からj個の切れ目を選ぶこと」にうまく帰着できないため失敗したと思われる。たしかに、i+1個目の切れ端を選んだ時点で長さがLじゃなくなってしまうのはあまりにまずい解法な気がする。
・一つのアルゴリズムにこだわりすぎるのはよくない。

## 適切な方針
・貪欲法で「x以上のスコアを実現できるか」を判定する。それを用いて二分探索で実行可能な領域の最大値の探索。
・スコアxで実現可能ならスコアx-1でも実現可能、という最小値の性質を活かした解法。
・あるスコアxに関して実行可能かどうかが貪欲法でO(N)で全探索して判定できることに気づいて、**その実行可能領域が上または下のみに有界なら二分探索で境界を求められる** って思考をすべきだった。言われてみればそりゃそうかって話。
・解けなかったの悔しい。次は解きたい。

## 解説付きコード

```
#すべての長さをx以上にできるかどうか判定する関数
def is_cutable(x, N, A):
  #何回切ったか
  num = 0
  #最後に切ったのはいつか
  pre = 0
  
  #xを超えたタイミングで切っていく
  for i in range(N):
    if A[i] - pre >= x:
      num += 1
      pre = A[i]
      
  #Lから最後のpreまでのあまりも、x以上なら切ったと考える
  if L - pre >= x:
    num += 1
  
  #numにはx以上の切れ端の数が格納されている。
  #numがK+1を超える→切れ端をK+1個用意できる→K回切った上で最小の切れ端はx以上
  return (num >= K + 1)
 
[N, L] = list(map(int, input().split()))
K = int(input())
A = list(map(int, input().split()))

#二分探索(最大のxを探しにゆくのさ)
left = -1
right = L+1

while (right - left) > 1:
  mid = (left + right) // 2
  
  #midになるよう切れるなら探索範囲はmidより上側
  if is_cutable(mid, N ,A):
    left = mid
  
  #midになるよう切れないなら探索範囲はmidより下側
  else:
    right = mid

print(left)
```

## 参考コード
https://drken1215.hatenablog.com/entry/2021/06/12/020300
bat gcc build sample & remain in same folder

## pushd & popd

```batch
set source=TwsApiL0
set exe=%source%_64
pushd TwsApiC++\Src
g++ -D _WIN64 -D CorrectAfxWinIncluded -shared -static -static-libgcc -static-libstdc++ -s -std=gnu++20 %source%.cpp -I..\Src -I..\..\source\PosixClient\Shared -I..\..\source\PosixClient\src -I..\Api -Wl,--no-as-needed -o ..\Api\TwsCppApi_64.dll -Wno-deprecated -lwsock32 -lws2_32 -lpthread
popd
```
mingw setup 

```bat
@echo off

set repo_owner=niXman
set repo_name=mingw-builds-binaries
set unzip_path=C:
set url=https://www.7-zip.org/a/7z2201.exe
set installer_file=7z2201.exe

set "SEVENZIP_EXE=C:\Program Files (x86)\7-Zip\7z.exe"
if not exist "%SEVENZIP_EXE%" (
  echo 7zip is not installed, downloading installer...
  curl -L -o %installer_file% %url%
  echo Installing 7zip...
  start /wait %installer_file%
)

echo Retrieving latest release information...
for /f "usebackq tokens=2 delims== " %%G in (`curl -s https://api.github.com/repos/%repo_owner%/%repo_name%/releases/latest ^| findstr "browser_download_url"`) do set url=%%~G

if not exist "%unzip_path%" mkdir "%unzip_path%"

for /f "tokens=*" %%F in ("%url%") do set zip_file=%%~nxF

if not exist "%zip_file%" (
  echo Downloading %zip_file%...
  curl -L -o %zip_file% %url%
)

echo Extracting files to %unzip_path%...
"%SEVENZIP_EXE%" x "%zip_file%" -o"%unzip_path%"

echo %unzip_path%\mingw64\bin
setx PATH "%unzip_path%\mingw64\bin;%PATH%" /M

echo Done!
```
業務プロセスおよび業務理解度の評価指標

業務改善をやる機会が多いので、備忘録として、本記事を書いています。

＜関連記事＞
[業務改善および標準・フォーマット作成のポイント](https://qiita.com/KisaragiMiku/items/84bdf01cbbe4832dd92b)

# 業務プロセスの評価指標
業務プロセスに対する評価指標を考えてみました。
| 評価 | 説明 |
|:-----|:-----|
| 1 『属人化』|プロセスが確立していない |
| 2 『部分標準化』| 小規模で標準化されている (PJ、チーム、課内メンバーなど) |
| 3 『組織標準化』| 組織で基本的なプロセスが標準化されている（部、事業部など） |
| 4 『テーラリング化』| 組織で基本プロセをベースにテーラリングされている|
| 5 『最適化』| 定期的にレビューされ最適化されている |

開発プロセスなど広い定義に適用するのではなく、開発プロセス＞要件定義＞競合他社調査手順のようにある程度詳細化して適用することで、プロセスを適切に評価できると思います。

# 業務理解度の評価指標
業務理解度に対する評価指標も考えてみました。
| 評価 | 説明 |備考|
|:-----|:----|:---|
| 1 | プロセス、標準を把握していない。|指示が必要。|
| 2 | 自部署のプロセス、標準を把握しているが、法的根拠を理解していない。<br> 他部署のプロセス、標準を把握していない。|自部署業務遂行は可能。|
| 3 | 自部署のプロセス、標準を把握しており、法的根拠理解している。<br> 他部署のプロセス、標準は把握していない。|他部署に影響しない自部署の業務改善可能。|
| 4 | 自部署のプロセス、標準を把握しており、法的根拠理解している。<br> 他部署のプロセス、標準の一部を把握しており、自部署の成果物が他部署にどのように影響するか理解している。|監査の応対可能。<br>他部署に影響する業務改善可能。|
| 5 | 法規制を解釈し、自部署または他部署のプロセス、標準に落とし込める。||

3以上は業務改善可能ですが、効率化を考慮できない人（法規制に重心を置きすぎる人）は改善業務にアサインしないことを推奨します。
監査員の指摘を恐れて、非効率なプロセスが形成される可能性があります。
TLS1.0、TLS1.1の廃止されていた

はじめに
=

様々な通信で安全を確保するために重要なTLS通信。
そのバージョンはTLS1.0に始まり、TLS1.1、TLS1.2と続き現在はTLS1.3と4つのバージョンがあります。
私が脆弱性診断をしていた頃はTLS1.3が少しずつ普及していた頃でTLS1.0とTLS1.2を多くの会社のサーバで利用されていました。

Nessasの評価
=
最近、大規模な脆弱性診断を行うプロジェクトに参加することになり、Nesaasのプラグインなどについて調査をしていたところ驚きました。
NessasがTLS1.0をMEDIUMの脆弱性として検知していました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3341186/e7ba16dd-0b05-dc94-f7a0-546436e92ada.png)

当時、リリース前だったPCI DSSv4ではTLS1.0、TLS1.1を禁止するというような噂も聞いてはいたが、Nessasの情報を見るとPCI DSSv3.2から禁止となっているようでした。

ブラウザの対応
=
私が現役でやっていた頃の知識はもう古い物なんだなと思いながら色々と調べることにしてみました。
古いTLSが推奨されていないとは言え、インターネット上に公開しているWEBサーバを立てるとき、
無効化してしまうと表示できないユーザが出てきてしまうなどの不都合が起きて困ると思うけど、最近はどうやってるんだろうかと疑問を持ちました。
さらに調べてみると2020年から2021年の間にChromeやFireFoxなどのブラウザでも無効化しているようで、普通にインターネットを利用している人はTLS1.2以上を利用しているみたいで、TLS1.1以前が無効化しても問題ないようでした。

WEB系はあまり強くはないけどセキュリティの仕事をやっている身としては、情報をしっかりアップデートしていかないと恥をかくこともあるなと感じました。
数値を0で割った時にZeroDivisionErrorが返ってこない件

## 初めに例外処理の使い方
基本
```
begin
  # エラーを発生させる可能性のあるコード。
rescue
  # エラー発生時の処理。
end
```
例
```
begin
  p num1 / num2
rescue => e 
  p e.message #=> error
end
```
エラーを変数eに格納しmessageメソッドでエラー内容を表示。
## 詰まったこと
割り算の際に0で割ると、ZeroDivisionErrorが返ってきて
「0による割り算は許可されていません」と出力させたい。
num1,num2をgets.chomp.to_iとするとZeroDivisionErrorがしっかり返ってきてくる。
```
puts '1番目の整数を入力してください:'
num1 = gets.chomp.to_f
puts '2番目の整数を入力してください:'
num2 = gets.chomp.to_f

begin
  p num1 / num2
rescue ZeroDivisionError => e
  p e.message
  p '0による割り算は許可されていません'
rescue => e
  p e.message
end
```
## 解決方法
```
raise ZeroDivisionError if num2.zero?
```
num2に0が入力されたときはZeroDivisionErrorを返すコードを書く
## 原因
浮動小数点(Float型)/0をしたときはInfinityが返ってくる仕様だった。
https://docs.ruby-lang.org/ja/latest/method/Float/i/=2f.html

## 最後に
原因は簡単なことだった。
しかし他の箇所のコードが間違っているのではないのかと思って調べており、時間を要した。
まずは公式ドキュメントを読むように心がける。
Windows 10 IoT Coreをダウンロードする

:::note warn
Windows 10 IoT Coreの最終版であるVersion 1809のサポートは2020年11月10日に終了しました。
https://learn.microsoft.com/ja-jp/lifecycle/products/windows-10-iot-core

Windows IoT Core サービスへの移行を検討してください。
http://aka.ms/IoTCoreServices
:::

# 入手に迷ったソフトウェア
https://learn.microsoft.com/ja-jp/windows-hardware/manufacture/iot/set-up-your-pc-to-customize-iot-core のソフトウェアのうち、下記2つのプログラムに迷ったので記録しておきます。

## Windows 10 IoT Core パッケージ
3月まではダウンロードページが存在していたようですが、現在はアクセスできません。
http://web.archive.org/web/20230316162319/https://www.microsoft.com/en-us/software-download/windows10iotcore

当時ダウンロードできたファイルと同等かはわかりませんが、https://software-download.microsoft.com/download/sg/17763.107.181026-1406.rs5_release_svc_prod2_amd64fre_IOTCORE_PACKAGES.iso (BW10AA_MULFREO_EN-US_DV9) からダウンロードできるようです。

## IoT Core ADK アドオン
`17763-v7`ブランチは`Windows 10 IoT Core release 10.0.17763.1577`以降のみサポートしているため、上記のビルドを使用する場合は、v6.0を使うことになりそうです。
https://github.com/ms-iot/iot-adk-addonkit/releases/tag/v6.0
Laravelでサクッと申請書を出力するネタWebサービスを作ってみた

# はじめに
簡単に少し入力するだけで
サクッと申請書を発行できるWebサービスを作った

## 経緯
とある友人がすぐ人に飯を奢らせようとしたり、逆に人に飯を奢らされそうになっていて
「管理が大変そうだなぁ」と思い、
どうせなら申請書で管理しては如何かと申請書をサクッと発行できるアプリを作ってみた。

## 環境構築

|環境|概要|詳細|
|-|-|-|
|インフラ|Lightsail|LAMPインスタンス1G|
|ドメイン|お名前.com|ひみつ|
|バックエンド|PHP|Laravel 10|
|フロント|PHP|Laravel Blade|

### サーバ
プライベートは専らXserverで定額課金の民。
従量課金であるAWSはまだ怖い🥺
でもAWSもちょこっと使ってみても良いかな。。。

ということでサーバ周りは、
以前WordPressの業務で触ったことのある`Lightsail`のLAMP環境（PHP8.1）にしてみた。

定額の安心感たるや。

### ドメイン
お名前.comで破格の1円で仕入れたドメインを使っちゃう。
優しいのでSSL化の対応までしています。優しい。



### バックエンド＆フロントエンド
オラァ、Laravel一択だで💪💪💪💪
フロント・・・？なにそれ美味しいのかしら
男は黙って"""**Blade**""""🔪

### 補足
ワァッ...!Docker環境構築してるうちに熱が冷めちゃった...!
なんてことを防ぎたかったので今回は直でリリース環境を構築。
PHP Stormの同期とGithubでいい感じにする見切り発車！

なので、リリース後もアプリが触れなかったり、
Basic認証になったりすることがあります。ゆるして。


# 仕様
* URL：`/`のみのページ構成とする
    * クエリストリングにtokenを持つ場合
        * token一致するかつ有効期限内（３日間）の申請書を出力する
        * PDFデータは保存せず、都度出力とする
    * クエリストリングにtokenを持たない場合
        * 以下のパラメータを指定
       
            |クエリパラメータ|内容|入力|出力|
            |-|-|-|-|
            |approver|承認者|任意|（入力された場合のみ）入力値に「殿」を末尾に付与して出力|
            |applicant_department|申請者所属|任意|（入力された場合のみ）入力値を出力|
            |applicant_name|申請者名|**必須**|入力値を出力|
            |application_title|申請概要|**必須**|入力値を出力|
            |application_content|申請内容|**必須**|入力値を出力|

・入力情報はデータベースに保存する
・有効期限を設け、3日間の間のみ参照（生成）が可能とする

## ルーティングと処理概要
1. `/`：入力ページ兼PDF発行ページ
    1. 入力フォームを表示（入力してsubmitを行う）
    1. `token`が未設定のため、GETパラメータで渡した入力値を入力値をデータベースに保存する
    1. 2.で保存したレコードのトークンをクエリストリングに設定してindexページへリダイレクト
    1. `token`が設定済みのため、PDF出力処理を実行

## PDF発行
1. 申請書のテンプレートをスプレットシートで作る
1. サーバ上に格納する
1. テンプレートの上に文字をプロット（古のTCPDF/FPDIを使用）
1. ブラウザでPDFを返す


※ライブラリはDomPDFも試してみたけど、
　CSSの調整してるうちに飽きちゃいそうでやめました。

## 出力結果
URLを叩くとこんな感じでPDFが出力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2721358/77c15802-2cc7-3048-6ffc-b068ea28b444.png)

1. URLにアクセス
2. フォームに項目を入力し、発行ボタンを押す
3. ブラウザにPDFが表示される

# まとめ

友人とふざけるためだったり、
自分の生活を豊かにするためだったり
ネタに対するモチベーションって意外と強い説。

# 参考にさせていただきました、感謝
https://juno-engineer.com/article/amazon-lightsail-lamp-php8-laravel/#autoid-11

https://qiita.com/morita-toyscreation/items/89283c37bc15438ac138
【Python】リストの積の計算時間

# 概要
コードを書いていて気になったので， リストの積を計算する際にかかる時間を以下の3パターンで測ってみました．

1. listをfor文で回す
1. mathモジュールを使う
1. numpyを使う

以下は実際に動かしたコード．
```prod_time.py
import time

start = time.time()
A = [1] * 100000000 
ans = 1
for a in A:
    ans *= a
print("list loop:", time.time() - start)


import math
start = time.time()
ans = math.prod(A)
print("math.prod:", time.time() - start)


import numpy as np
start = time.time()
ans = np.prod(A)
print("numpy.prod:", time.time() - start)
```
出力結果は次のとおり．
```
list loop: 3.508364677429199
math.prod: 0.47490572929382324
numpy.prod: 2.398198127746582
```

# 結果
表にまとめると，
|  方法  |  計算時間  |
| ---- | ---- |
|  for文  |  3.508364677429199  |
|  math.prod()  | 0.47490572929382324 |
|  numpy.prod()  | 2.398198127746582  |

どうやらmathモジュールを使う場合がかなり高速のようです！
※ちなみにAtcoderのpypy3ではバージョン的にmath.prod()は使えない (2023/4/24時点）
AWS Glue Crawlerで異なる構造を持つ複数のcsvをまとめてクロールするとデータが空になる

AWS Glue Crawlerで複数csvから一括でデータカタログを作ったときにデータが空になったときの対処法

# 結論
csvをまとめてクロールする場合は構造別にフォルダを分けてやる必要があります。

# 概要
複数のcsvデータをまとめてデータカタログ化する。
以下のサンプルデータをまとめてクロールしてAthenaで見れるところまでやります。

### サンプルデータ
```user.csv
"user_id","name"
1,"hoge taro"
2,"hoge jiro"
3,"hoge sanro"
```
```user_image.csv
"user_id","image_url"
1,"https://hoge_taro_image.jpg"
2,"https://hoge_jiro_image.jpg"
3,"https://hoge_sanro_image.jpg"
```

# 空データの再現
サンプルデータを配置するS3バケットパスはS3://sample/inputとしておきます。
S3://sample/input/user.csv
S3://sample/input/user_image.csv

一見S3://sample/inputをクロールすれば問題なさそうですね。
しかしテーブルとスキーマは正しいのにデータが空の状態になります。
![S1_empty_athena.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547361/2ada54c2-d389-910a-42e8-4177a0b1e212.png)

# 対策
この現象はAWS Knowledge Centerで解説されています。
Data for multiple tables stored in the same S3 prefixの項目

https://repost.aws/en/knowledge-center/athena-empty-results

説明通りに各構造でフォルダ分けします。
S3://sample/input/user/user.csv
S3://sample/input/user_image/user_image.csv

これでS3://sample/inputを再度クロールすることで無事にデータを確認できました。
![S1_Athena_has_records.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547361/434a5da4-60ae-aa4b-42c2-e47b25611da6.png)

# おまけ1
csvの数が多くなると手動でのフォルダ分けは面倒になります。
AWS Glue ETL Jobを使った自動フォルダ分けを追々紹介します。

# おまけ2
このままだとデータにダブルクォーテーションが付いているため扱いづらいです。
データのみ抽出する方法を追々紹介します。
HackTheBox Fawn Writeup

# はじめに

本記事は「[HackTheBox:Fawn](https://app.hackthebox.com/starting-point)」のwriteupです。

## 問題

FTPでサーバに乗り込みフラグを探す問題です。

## 回答

とりあえず、ポートスキャンします。
`ftp(tcp/21)`が公開されていることがわかりました。

```text
┌──(kali㉿kali)-[~]
└─$ nmap -sV 10.129.1.14
Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-24 00:06 JST
Nmap scan report for 10.129.1.14
Host is up (0.18s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
Service Info: OS: Unix

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.74 seconds
```

次に、`ftp`コマンドでサーバに繋いでみます。
`anonymous`ユーザでアクセスできるか試してみます（anonymous FTP）。

以下は`anonymous FTP`についての抜粋です。

```text
anonymous FTPとは、インターネットなどのTCP/IPネットワーク上でファイルの送受信を行うFTPを、誰でも匿名で自由に利用できるようにする仕組み。不特定多数へのソフトウェアやデータの公開・配布などのために利用される。
https://e-words.jp/w/anonymous_FTP.html より
```

無事ログインすることができました。

```text
┌──(kali㉿kali)-[~]
└─$ ftp 10.129.1.14
Connected to 10.129.1.14.
220 (vsFTPd 3.0.3)
Name (10.129.1.14:kali): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
```

`ls`するとカレントディレクトリのファイル一覧が表示されます。
`flag.txt`というフラグが記載されていそうなファイルがありました。
`get`で指定したファイルを接続元にダウンロードさせることができます。

```text
ftp> ls
229 Entering Extended Passive Mode (|||20192|)
150 Here comes the directory listing.
-rw-r--r--    1 0        0              32 Jun 04  2021 flag.txt
226 Directory send OK.
ftp> get flag.txt
local: flag.txt remote: flag.txt
229 Entering Extended Passive Mode (|||41131|)
150 Opening BINARY mode data connection for flag.txt (32 bytes).
100% |********************************|    32       75.12 KiB/s    00:00 ETA
226 Transfer complete.
32 bytes received in 00:00 (0.17 KiB/s)
ftp> exit
221 Goodbye.
```

接続元を確認したところ`flag.txt`がダウンロードされており、フラグが記載されていることが確認できました。

```text
┌──(kali㉿kali)-[~]
└─$ ls
Desktop    Downloads  Pictures  Templates  flag.txt
Documents  Music      Public    Videos
```
RaspberryPi で WS281X LEDストリップをマルチチャンネル駆動する

「Raspberry Pi 16-channel WS2812 NeoPixel LED driver &#8211; Lean」
https://iosoft.blog/2020/09/29/raspberry-pi-multi-channel-ws2812/

で、最大16チャンネルの WS281X LEDストリップを駆動する方法が記されている。

コード：https://github.com/jbentham/rpi

これは、 RaspberryPi の セカンダリメモリインターフェイス (SMI) を使って正確な信号を生成するもの。
SMI は 18ch 使えるらしいが、記事で紹介されているのは 8ch ないし 16ch 。 SMI バス信号は SD0〜SD17となっていて、GPIO 8~25 に割り当てられている。

今回はこの記事を元に GPIO8〜15 を使って 8ch を制御してみた。
試してみたらちょっとコツが必要だったので記事化。


# 環境


- Raspberry Pi 3
- Raspberry Pi OS Lite
- Release date: February 21st 2023
- System: 32-bit


# ダウンロード
```
$ git clone https://github.com/jbentham/rpi_multichannel_ws281x.git
```

# 編集

Raspberry Pi 3 にあわせて `rpi_dma_utils.h` を編集

```
// Location of peripheral registers in physical memory
#define PHYS_REG_BASE   PI_01_REG_BASE
#define PI_01_REG_BASE  0x20000000  // Pi Zero or 1
#define PI_23_REG_BASE  0x3F000000  // Pi 2 or 3
#define PI_4_REG_BASE   0xFE000000  // Pi 4

//#define CLOCK_HZ      250000000   // Pi 2 - 4
#define CLOCK_HZ        400000000   // Pi Zero


```
↓
```
// Location of peripheral registers in physical memory
#define PHYS_REG_BASE   PI_23_REG_BASE
#define PI_01_REG_BASE  0x20000000  // Pi Zero or 1
#define PI_23_REG_BASE  0x3F000000  // Pi 2 or 3
#define PI_4_REG_BASE   0xFE000000  // Pi 4

#define CLOCK_HZ      250000000   // Pi 2 - 4
//#define CLOCK_HZ        400000000   // Pi Zero


```

# コンパイル

```
$ gcc -Wall -z muldefs -o rpi_pixleds rpi_pixleds.c rpi_dma_utils.c
```

# 実行

3つのチャンネルの1つのLEDをそれぞれ指定色で光らせます。
```
$ sudo ./rpi_pixleds 7f0000 007f00 00007f
VC mem handle 2, phys 0xfebf8000, virt 0x76fb2000
Setting 1 LED per channel, 8 channels
Closing
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/edff11e1-5871-60a8-b21e-2516fca21146.png)

チャンネルごとに5つのLEDをテストパターンで光らせます。

```
$ sudo ./rpi_pixleds -n 5 -t
VC mem handle 2, phys 0xfebf8000, virt 0x76f0f000
Testing 5 LEDs per channel, 8 channels
```

# アレンジ

フォークして新しいレポジトリを作ってみました。
https://github.com/nanbuwks/rpi_multichannel_ws281x

rpi_8chwave というコマンドで、8ch を波のように光らせることができます。

```
 $ sudo ./rpi_8chwave -n 100 -w 100 -B 10 FF0000 00FF00 0000FF FFFF00 00FFFF FF00FF 808080 FFFFFF 
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5b4d05b6-8483-d17e-316d-650285fef25f.png)

それぞれのチャンネルごとに、RGB色コードを指定します。消灯の場合は色コード 00000 を与えます。


その他、主なオプションは以下の通りです。

- `-W`  ウェイトを指定することで、速度を調整できます。
- `-B`  0~100% の明るさ
- `-n`  1チャンネルでのLED数
【受験記録】応用情報技術者試験

# 応用情報大変だった話
応用情報技術者試験（以下、応用情報）を勉強してきました。数学科ということもあり、資格試験系は手が出しづらい環境にあるのですが、いろいろな方に励まされてどうにかやり切ることができたので共有します。

:::note alert
まだ、合否が出ていないけど記録として書いておこうと思ったしがない大学院生の感想戦です。
:::

### 応用情報技術者試験が何ぞやって人は以下を確認してね
https://www.ipa.go.jp/shiken/kubun/ap.html

## あんたどれくらいできるの？
１年前の春季に基本情報技術者試験を獲得しています。「学部生のうちにAPまで取得するぞ！」なんて息巻いていました。
しかし、秋季の応用情報に**応募し損ねる**というミスを犯します。とんでもない野郎ですね。長期インターン先のメンターさんも苦笑いでした。
そんなこんなで、基本情報の内容をうろ覚えの状態で臨んだわけです。

## どのくらい勉強したの？
本腰を入れたのが**３週間前**でした。それまでは暇があるときに午前問題をゲーム感覚で解いていました。
大学院が始まりそうになり、「あれ？これ学校始まったら勉強できなくね？」と気づいて春休み最後の週から取り組み始めた記憶があります。
深夜まできっちり勉強していたので、勉強時間はなんだかんだいって100時間程度だと思います。
ただ、あんまりここら辺は**関係ない**と思います。理由は後でいいます。

## どういうところが大変？
大変なところは「**午後問題における知識を必要とする回答**」これに尽きます。
以下、午前・午後に分けて対策と共にお話しします。

## どういう対策を立てた？
### 午前問題
正直言って**基本情報と何も変わらない**です。違いを明確に挙げる方が難しい。
基本情報もそうですが、応用情報も**過去問題**を解くことから勉強を始めました。基本然り応用然り、問題となる範囲が広すぎます。
なので、参考書ではカバーしきれないんですよね。だから読んでもあまり得しません。そもそも応用情報を受ける人は基本情報の知識と大方被ってもいます。

自分は、直近の1年間を除き、過去6年分の過去問をとにかくやりました。
なんだったら、8割以上は問題を見たら即答するくらいのほぼ暗記状態でした。試験では、聞かれ方がある程度固定されています。
なので、ニュアンスを変えて聞いてくるようなことをしません。だから、暗記がとっても対策になるんですよね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3341148/e041f443-e9d7-2b65-0f47-76242d1e3bd0.png)
こういう問題とか、「主活動・支援活動」と出てきただけで「バリューチェーンだな」と感じられるまでできるとGoodです。もう早押しですね。

:::note info
おすすめ：午後問題に向けて、自分が**どの分野の単語の意味なら覚えられそうか**意識するといいかもしれません。
「○○正規形みたいな単語難しいから自分はデータベース系は苦手そうだな」とか「セキュリティ関係の用語は比較的イメージしやすいな」とかですね。
:::

### 午後問題
午前が知識を「写す」問題なら、午後は知識を「使う」問題です。
なので、ようやくそれぞれの単語の意味と使われ方を**覚える**必要があることに気が付きました。
午前問題を解いていて、正答率と感触が良いものが、午後問題のジャンルのどれなのか当てはめ、以下を勉強しました。

* 情報セキュリティ（必須）
* 経営戦略
* システムアーキテクチャ
* ネットワーク
* 組込みシステム開発
* システム監査

:::note warn
これ以外のジャンルは、一度も過去問を解いていません。
プログラミングは受けようかなとも思いましたが、試験日までの日程を踏まえて、ものにするだけの時間がないと判断して捨てました。
:::

あとは、このジャンルで扱われている単語を午前午後合わせてすべて拾ってきて、単語帳にメモしました。
ここで、単語帳を作るうえで**「単語⇒文章」と「文章⇒単語」をそれぞれ作成した**のがかなり良かった気がします。

なぜなら、午後問題は午前と違って**ニュアンスが変化する**んですよね。なので、午前のような暗記ではなく**イメージ**から覚えることが重要だと考えました。
とにかく「単語帳 ⇒ 午後問題を解く ⇒ 単語帳 ⇒ ・・・」をずっと繰り返していました。

ここで意識したことが「**答えは必ず問題文に眠っている**」と「**気になったことは全てメモして検討する**」ですね。
#### 答えは必ず問題文に眠っている
この言葉を頭の中で反芻しながら、過去問を解いていました。答えに迷っても、必ず問題文のどこかに糸口があるんですよね。
自分が選んだ科目が特に文章多めな科目なので、解いてく上で確立されたポリシーでした。

#### 気になったことは全てメモして検討する
情報セキュリティやシステム監査の問題における奴らの戦法としてありがちなのが、**情報を羅列していって本筋を隠すこと**です。
ちょっとした隅で、ボソッと言ってそれが答えになることがあります。
なので、上から読んでいき、とにかく気になったことまとめるようにしました。具体的には、箇条書きで書いて、情報がつながる部分は線で結んだりしてました。
問題を一通り解き終わったときに箇条書きのリストを見て、「**気になったことがすべて解消されているか**」を確認することで、漏れのない"読み"を目指しました。

## 試験は実際どんなだった？
試験会場は、都内の大学でした。意外と周りの型の年齢が分かりずらかったです。みんな大学生に見えました笑。
女性の方も多かったです。基本情報のときは、男性がほとんどだったので（たまたまだと思いますが）男女共に目指す人がいる試験なんだなと少し感動しました。

午前問題は、なんとなく過去問題からの輸入が少なかったように思えます。
新しい用語を聞いてくる問題が多かったので「これは計算問題とか落とせないぞ」と割と早めに覚悟しました。

午後問題は、いつも通りという感じです。
対策の部分でも述べましたが「**答えは必ず問題文に眠っている**」と「**気になったことは全てメモして検討する**」を徹底しました。
ただいくつかの知識を要する選択問題に迷いに迷った感じです。

## 終わってみてどうだった？
結果は、まだ返ってきてませんが、落ちても同じように３週間前あたりから勉強し直すんだろうなと思います。
とにかく、やり切ったことはやり切ったので、研究と簿記の受験に備えようと思います。。。。
Godot4.0でジャイロセンサー使ってみた（Androidスマホ実行限定）


　ゲームエンジンGodot4.0で3Dスマホゲームを作りたいと思いますが、その前にお勉強しています。
　2023/4/4リリースのGodot_v4.0.2-stable_win64を使用しています。

# 目的
　スマホゲームの入力としてジャイロセンサーを使ってみます。
　3D空間に物体を浮かせて、Androidスマホの傾きをジャイロスコープで検出して立方体を回転します。

# Godot4.0でジャイロセンサーを読みだす方法
　Inputクラスにget_gyroscope()APIがあるので簡単に取得できます。
　「スマホデバイス」のX,Y,Z座標系の軸毎の回転速度をrad/sの単位で取得します。
　スマホを見て、左右がX軸、上下がY軸で奥行方向がZ軸のようです。

>Vector3 get_gyroscope ( ) const
>https://docs.godotengine.org/en/latest/classes/class_input.html#class-input-method-get-gyroscope

:::note
 AndroidもしくはiOS上で実行する必要があります。本記事ではAndroidで実行確認をしました。
:::

# 新規シーンを作成する
　ジャイロスコープのテストをするためにシーンを作成します。カメラとライトと立方体が1個あるシーンです。

| ノード名:ノードクラス名 |インスペクタ変更値|
|:-|:-|
|World : Node3D||
|　┝━Camera3D|Position : (0m, 5m, 0m)  Rotation : (-90°, 0°, 0°)
|　┝━DirectionalLight3D|Position : (-10m, 0m, 0m)  Rotation : (-10°, 45°, 0°) shadow:オン|
|　┗━MeshInstance3D|新規BoxMesh3D|　　

　下記のようになります（スクリプトをアタッチしたあとです）
![スクリーンショット (720).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/19b1e739-7a81-534c-f92b-43b66952cf58.png)
# スクリプトの実装
　シーン内のWorldを右クリックしてスクリプトにアタッチを実行します。
　world.gdという名前で作成します。

　下記のように修正します。
```GDScript
extends Node3D

func _physics_process(delta):
	var v3_gyro_rad = Input.get_gyroscope()
	$MeshInstance3D.rotate_y( -v3_gyro_rad.z * delta)
	$MeshInstance3D.rotate_z(  v3_gyro_rad.y * delta)
	$MeshInstance3D.rotate_x( -v3_gyro_rad.x * delta)
```
　スマホの座標系とGodotエンジンの座標系の違いで、ZとY軸を入れ替えて設定します。
　符号も変換していますが、正直、実際の値を見て上記の実装をしました。
　Input.get_gyroscope()で取得する値はrad/sなので、deltaを掛け算した値をrotate_x/y/zメソッドに渡しています。

>Androidのセンサー座標系
>https://developer.android.com/guide/topics/sensors/sensors_overview?hl=ja#sensors-coords

# 一旦Windowsで実行します。
　一度Windows版で実行できるか確認します。
　実行して中央に正方形が表示されればOKです。

# Androidアプリとしてエクスポートします。
　下記の記事を参考にしていただければ幸いです。

https://qiita.com/FootInGlow/items/cde673e0a424413ca109

# Androidスマホで実行します。
　背景が映り込まないように、真っ暗な室内でスマホの実行画面を撮影しました。
　起動直後。
![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/57115ffd-91f6-2954-e5f0-db794165c943.jpeg)
　スマホを左に傾けたとき。
　立方体を回転しているので光の当たり方がかわるため、写真では起動直後に見えていた面がどこに移動したかわかりにくいですね。ライトも一緒に回転したほうよかったと思います。
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/cd2d96ac-acf3-8162-8ac8-2d8f6e9752cd.jpeg)
　スマホを右に傾けたとき。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/403087f4-6990-950d-ac3f-c21124224ca7.jpeg)
　スマホを奥に傾けたとき。
![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/e0e1aa5b-04c0-0f22-3cd5-be330c1d98ca.jpeg)
　スマホを手前に傾けたとき。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/3241561e-52a7-cbd4-c6aa-3364cdab98b6.jpeg)

# github

https://github.com/footinglow/Godot4/tree/main/03_study/GyroscopeSample

以上
Rubyを2週間勉強して躓いた2点

初めまして、1つ目の技術ブログです。
今回は2週間Rubyを勉強しブラックジャックゲームの実装まで行った今の時点での躓いた点をメモ程度に書き残します。
こういった記事やブログの書き方に慣れていないので、メモ程度としてご覧ください。
①オブジェクト指向について
　一番長く、大きく躓いたポイントです。
　はじめのうちにブログ記事等でざっくりした説明だけを読んで満足したのが良くなく、実践的な部分が何も入っていなかった。基礎の説明とは別にコードを伴った教材が必要不可欠。

②Rubyの基礎の部分
　こちらもざっくりとした動き方だけを学んで、出来た気になっていた。実際に1つのプログラムを実装しようとすると初学者だとエラーと戦う事になるのでとにかく基礎の理解、エラー分の理解。
また、自分の力だけで難しければ早めにRubocop等のコード解析ツールを用いることで、正解にたどり着きやすい。

2点とも通じて、学んでみれば単純だったことを知らないまま時間だけをかけて大変な思いをしたと思う。
HackTheBox Meow Writeup

# はじめに

本記事は「[HackTheBox:Meow](https://app.hackthebox.com/starting-point)」のwriteupです。

## 問題

telnetでサーバに乗り込みフラグを探す問題です。

## 回答

とりあえず、ポートスキャンします。
`nmap -sV`でサービスポートの開閉状態に加えサービスのバージョンも出力します。
今回用意されているサーバでは`telnet(tcp/23)`が公開されていることがわかりました。

```text
┌──(kali㉿kali)-[~]
└─$ nmap -sV 10.129.220.188
Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-23 23:13 JST
Nmap scan report for 10.129.220.188
Host is up (0.17s latency).
Not shown: 996 closed tcp ports (conn-refused)
PORT      STATE    SERVICE  VERSION
23/tcp    open     telnet   Linux telnetd
7025/tcp  filtered vmsvc-2
8873/tcp  filtered dxspider
24800/tcp filtered unknown
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 36.70 seconds
```

次に、`telnet`コマンドでサーバに繋いでみます。
設問に記載されているように`root`はパスワードなしでログインできるようなので、試したところ無事ログインできました。

```text
┌──(kali㉿kali)-[~]
└─$ telnet 10.129.220.188
Trying 10.129.220.188...
Connected to 10.129.220.188.
Escape character is '^]'.

  █  █         ▐▌     ▄█▄ █          ▄▄▄▄
  █▄▄█ ▀▀█ █▀▀ ▐▌▄▀    █  █▀█ █▀█    █▌▄█ ▄▀▀▄ ▀▄▀
  █  █ █▄█ █▄▄ ▐█▀▄    █  █ █ █▄▄    █▌▄█ ▀▄▄▀ █▀█


Meow login: root
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-77-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun 23 Apr 2023 02:41:11 PM UTC

  System load:           0.0
  Usage of /:            41.7% of 7.75GB
  Memory usage:          4%
  Swap usage:            0%
  Processes:             136
  Users logged in:       0
  IPv4 address for eth0: 10.129.220.188
  IPv6 address for eth0: dead:beef::250:56ff:feb9:edc4

 * Super-optimized for small spaces - read how we shrank the memory
   footprint of MicroK8s to make it the smallest full K8s around.

   https://ubuntu.com/blog/microk8s-memory-optimisation

75 updates can be applied immediately.
31 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Mon Sep  6 15:15:23 UTC 2021 from 10.10.14.18 on pts/0
root@Meow:~#
```

カレントディレクトリで`ls`するとフラグが記載されたファイル`flag.txt`を確認することができました。

```text
root@Meow:~# ls
flag.txt  snap
```
近藤科学RCB-3対応コントローラーの通信プロトコルについて覚え書き


　近藤科学の旧式のロボット制御基板、RCB-3に対応するコントローラー（操縦装置）の通信方式である拡張低速シリアル通信のプロトコルは基本的には公式ドキュメントを参照すればよい、が…

- RCB-3/3Jコマンドリファレンス P.33 「拡張低速シリアル通信」

https://kondo-robot.com/w/wp-content/uploads/RCB3CommandRef.pdf



コマンドリファレンスに誤りがあり、下記の設定の方が正しいので要注意。

1. 通信速度 : 2400bps
1. データビット数 : 8bit
1. ストップビット : 1bit
1. パリティ **なし**


あと**論理反転**しているので、自作のマイコンで受信するときにはこれにも注意が必要だ。
arduinoならSoftwareSerial()の第3引数を設定することで簡単に受信できるので、自作のロボット等に活用することもたやすいだろう。


```cpp
#define MYRX 3 //デジタル3番ピンはソフトウェアシリアルRX
#define MYTX 2 //デジタル2番ピンはソフトウェアシリアルTX
SoftwareSerial mySerial(MYRX, MYTX, true);//(受信ピン,送信ピン,論理反転) 拡張低速シリアルは論理反転している
void setup()
{   
  mySerial.begin(2400);//AUXモード(RCB3規格拡張低速シリアル)受信機とArduino間は2400bps
  //以下略

```

---
　上記はネット検索すれば出てくる程度の情報ではあるが、古いハードについての情報でありそれらもいつまでアクセスできるかわからない、ゆえに改めてここにメモしておく。
cssを書いていたら半角スペース1個で詰まったけど、chatGPTに半分くらい助けられた話

# 何をしたかったか
aタグに対してCSSを適用して、hover時に色を反転させたようとしていました。
作成したコードが下記のコード。
```html:index.html
<table>
    <thead>
        <tr>
            <th>no1</th>
            <th>no2</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><a href="#"><div>a</div></a></td>
            <td>001</td>
        </tr>
    </tbody>
</table>
```
```css:style.css
table,td,th {
    border: 1px solid black;
}
td {
    width: 50px
}
a{
    display: inline-block;
    text-decoration: none;
    border: 5px solid blue;
}
a :hover {
    background-color: blue;
    color: white;
    border: 5px solid blue;
}
div {
    width: 40px;
}
```
# 何が起こったか
hoverした際にaタグの部分が大きくなり、行の高さが拡大してしまう。
chromeの開発者ツールを見るとborderが二重で適用されているように見える。
# 何が原因だったか
```css:style.css
a :hover {
    xxx:xxx
}
===>
a:hover {
    xxx:xxx
}
```
`a`と`:hover`の間に半角スペースが入っていたことが原因でした。
スペースがない場合、a要素のみに内部のコードが適用されます。
一方でスペースがある場合、a要素内のあらゆる要素に適用されるため、borderがa要素内にあるdivにも適用されてしまい、borderが２重になっていました。
# まとめ
chatGPTに「マウスを合わせた時にサイズが変化する要素はありますか」と聞いても「ありません」と帰ってきました。開発者ツールで見比べた結果、borderが2重に適用されていることを発見し、対処をchatGPTに聞いたところ、半角スペースが原因であることが発覚しました。
今回、プログラミングする上で、chatGPTを使っていますが、ほしい答えが得られる時と得られない時は五分五分といった感じでした。
Rubyのアクセス修飾子

## はじめに
今回がQiita初投稿です。
Rubyの勉強を始めて1ヶ月弱ですが、以前学習していたPHPとの仕様の違いに驚かされることが多いです。。その中でも今回はアクセス修飾子について備忘録も兼ねて記事に残そうと思います。

## PHPのアクセス修飾子
* public: どこからでもアクセス可能
* private: 同一のクラス内からのみアクセス可能（サブクラスからはアクセス不可）
* protected: 同一のクラスやサブクラス内からアクセス可能

## Rubyのアクセス修飾子
* public: どこからでもアクセス可能
* private: 同一のクラスやサブクラスのインスタンスメソッド内からアクセス可能
* protected: 同一のクラスやサブクラスのインスタンスメソッド内からレシーバ付きでアクセス可能

## 違いや注意点
まずRubyの場合、privateとprotectedの違いが分かりにくかったです。
privateはレシーバにselfしか設定できないのに対し、protectedは同じクラスをもとに作られたインスタンスであれば別のインスタンスでもアクセスできるという事でしょうか。
それと同時にRubyのprivateメソッドはオーバーライド可能で、サブクラス側でアクセス修飾子の変更が可能であることは注意が必要ですね。
PHPと比較した場合、Rubyのprivateはサブクラスからもアクセス可能なので柔軟な継承が可能になりそうですが、制限を厳しくして厳密なカプセル化を実現するという意味ではPHPのprivateの方が安心な気もします。

## あとがき
アクセス修飾子以外にもRuby特有の仕様が随所にあるので、少しずつ慣れていきたいと思います。
まだ理解が曖昧な部分も多いので、もし違う箇所等がありましたらぜひご教授いただきたく存じます。
PhpStormで個人的によく使用するショートカット6選(Mac版)

## 前置き
PhpStormを1年以上使ってきて、個人的によく使っているショートカットを紹介しようと思った次第です。
普段はMacを使っているので、Macのショートカットを紹介します。

## Shiftキー2回
ファイル検索ができます。
エラーログで出ているファイル名をすぐ開きたい時などに使用しています。

## command + Shift + F
プロジェクト内のテキスト検索ができます。
メソッド名など、細かな文字の検索をしたいときに使用します。

## command + L
ファイル内で指定した行に移動することができます。
エラーログで行数が出力されている時は、すぐにその行に移動したい為、マウスでファイルを上下移動するより速いです。

## command + E
開いたファイルの履歴を一覧で表示してくれます。
「さっき見てたファイルタブ消してしまった！」という時に使用することが多いです。

## command + J
PhpStorm内に登録されているスニペットを使うことができます。
スニペットのことをPhpStormでは、Live Templateというそうです。

何が登録されているかは、Preferences>Editor>Live Templatesで確認することができます。
また、自分好みのスニペットを作成して、登録することもできます。

## command + Shift + Enter
現在のステートメントを終了してくれます。
行終わりの;や{}など、地味に面倒なことを自動でやってくれます。

## まとめ
今回は6つ紹介しました。よく使っているショートカット6選といったところでしょうか。
まだ全部のショートカットキーを使っていないため、コーディングでやくに立ちそうなものがあればまた紹介していこうと思います。
また、作業スピードが速くなる便利なショートカットがあれば、コメントで教えて頂きたいです。
rubocopからの指摘と対応メモ（備忘録）

## はじめに
- Rubyを学習し始めて、まだ１か月。
Rubyのコーディング規約に則った記述かどうかのチェックをしてくれるrubocopの存在を知り、早速使ってみたものの、とんでもない数の指摘を受けてしまう結果に・・・。
- ちょっとしたスペルミスから、よくわからない改行の指摘までいろいろ。その都度、調べたり、指摘に沿って直したりしたことをメモとして残しておく。

## 指摘を受けた内容とその対応
- Line is too long.
（指摘の中身）
一行が長すぎる。
（対応策）
デフォルトで文字数が決められているらしく、これを上回らないように調整。

- Tab detected in indentation.
（指摘の中身）
インデントの中にタブが検出されました。
（対応策）
タブを半角スペースに置き換える。
インデントにタブキーを使っており、このことが、rubyのコーディング規約から
外れているので、指摘を受けたようだ。
置換でも何でも使って、一か所ずつ減らした。

- Missing top-level documentation comment for \`class XXXX`
（指摘の中身）
クラス定義の直上に、説明文（コメント）が見あたりません。
（対応策）
定義の一行上にコメントを入れる。
~~~ruby:例.rb
  # ここにコメントを入れておけば、ひとまず回避
  class Sample(i, j)
    @i = i
    @j = j
~~~
- Useless assignment to variable
（指摘の中身）
未使用の変数がある。
（対応策）
未使用でもないのにと随分悩んでいたが、調べてみると
戻値を明示しておくことが必要だったらしい。
~~~ruby:例.rb
  # 実際指摘を受けたコードを簡素化
  # rtnについての指摘
  def sample(str)
    if str = 'no'
      rtn += ' life'
    else
      rtn += ' money'
    end
    rtn  # <==ここの記述すると回避した。
  end
~~~ 

- Cyclomatic complexity for XXXX is too high
（指摘の中身）
分岐などの記述が多すぎる（複雑すぎる）
（対応策）
1\. メソッドなどにまとめて、切り出す。
2\. if文などの条件を見直す。
などが挙げられる。とにかく、シンプルにすることが大事。
見やすさ・読みやすさにも通じる。
:::note infomation
  そもそも、コードを書く前にしっかりとした設計してあれば、指摘を受けないのではと思い、反省。
:::

- Carriage return character missing.
改行コードにまつわる指摘だと思われるのですが、どうやっても減らなかった。
色々聞いてまわってみると、記述するときの改行コードを'CRLF'から'LF'に変えると良いとのことで試してみたが、全部が消えるわけではなかった。
⇒　もう少し、調べてみることにする。

## 終わりに
- rubocopは、Rubyのコーディング規約に則った記述かどうかを見るツールであるが、この規約は読みやすく、間違えにくくするために議論を重ねて作られたものだそうで、rubocopの指摘どおり、いつか修正していけば、読みやすいメンテナンスのしやすいものに近づけるのかも。
Xubuntu 23.04 Minimal のインストールメディアで「452: out of range pointer: 0x100010」と表示され起動しない問題への対応

# 症状

https://xubuntu.org/

　Xubuntu 23.04 Minimal を、インストールメディア(usbメモリ)を使って、2011年2月発売のネットブック(CPU:Atom N550,メモリ:2GB,SSD:120GB)にインストールしようとしたところ、
```
452: out of range pointer: 0x100010

Aborted. Press any key to exit.
```
または
```
452: out of range pointer: 0x7f43def0

Aborted. Press any key to exit.
```
と表示され、起動できなかった。
# 原因

https://rufus.ie/ja/

　Rufusを使ってインストールメディアを作ったことが原因と思われる。上はRufus3.22、下はRufus4.0で作成して起こった。
(2023.4.30追記)Rufus4.0.2035で解消されている。
# 対策

https://www.balena.io/etcher

　balenaEtcherを使ってインストールメディアを作成すると正常に起動した。

https://www.ventoy.net/en/index.html

　Ventoyを使っても正常に起動した。
音声合成の３つの方法

# はじめに

いままで、音声合成にgoogletts-cli.plを使用していましたが、WSLのUbuntu18からWSL2のUbuntu22.04.2に変更したところ、SOXのALSAエラーで音が出なくなった（対策がわからなかった）ので、他の方法も試したので、まとめてみました。
speak.shを作成し、使用してます。
使い方：
./speak.sh テキスト
# googletts-cli.plを使用
speak.shの内容
perl googletts-cli.pl -l ja -s 1.3 -t $1
■googletts-cli.plのソースの場所
(https://github.com/zaf/asterisk-googletts/blob/master/cli/googletts-cli.pl)
# gTTSを使用
speak.shの内容
python3 /home/pi/test.py $1 >> /dev/null
■プログラムtest.py
``` javascript
import sys
from gtts import gTTS
from playsound import playsound

tts = gTTS(sys.argv[1], lang='ja')
tts.save('gTTS_test.mp3')
# 音声再生
playsound("gTTS_test.mp3")
``` 
# VOICEVOXを使用
speak.shの内容
python3 /home/XXXXX/voicevox.py -id 1 -t $1
■プログラムvoicevox.py
``` javascript
import requests
import argparse
import json
from playsound import playsound

# VOICEVOXをインストールしたPCのホスト名を指定してください
HOSTNAME='192.168.XX.XX'

# コマンド引数
parser = argparse.ArgumentParser(description='VOICEVOX API')
parser.add_argument('-t','--text',  type=str, required=True, help='読み上げるテ>キスト')
parser.add_argument('-id','--speaker_id' , type=int, default=2, help='話者ID')
parser.add_argument('-f','--filename', type=str, default='voicevox', help='ファ>イル名')
parser.add_argument('-o','--output_path',  type=str, default='.', help='出力パス名')

# コマンド引数分析
args = parser.parse_args()
input_texts = args.text
speaker     = args.speaker_id
filename    = args.filename
output_path = args.output_path

#「 。」で文章を区切り１行ずつ音声合成させる
texts = input_texts.split('。')

# 音声合成処理のループ
for i, text in enumerate(texts):
    # 文字列が空の場合は処理しない
    if text == '': continue

    # audio_query (音声合成用のクエリを作成するAPI)
    res1 = requests.post('http://' + HOSTNAME + ':50021/audio_query',
                        params={'text': text, 'speaker': speaker, 'volume': 3.0})
    # synthesis (音声合成するAPI)
    res2 = requests.post('http://' + HOSTNAME + ':50021/synthesis',
                        params={'speaker': speaker},
                        data=json.dumps(res1.json()))
    # wavファイルに書き込み
    with open(output_path + '/' + filename + f'_%03d.wav' %i, mode='wb') as f:
        f.write(res2.content)
    # 音声再生
    playsound("./voicevox_000.wav")

``` 
【注意】（プログラムは「。」で音声ファイルを分けていますが、playsoundは音声ファイルを１つしか再生していません。テキストで「。」がある場合は別文字に変換して使用しています。）
HOSTNAMEはVOICEVOXのHTTPサーバ(run.exe)を起動しているPCのアドレスです。
PC側ではrun.exe起動時下記のオプションをつけてください。
run.exe --host 192.168.XX.XX
参考記事
Windows/Macに入れたVOICEVOXをPython経由で使う方法
(https://ponkichi.blog/voicevox-python-curl/)
Rubyのハッシュとキーワード引数であれ？となったこと

## はじめに

Rubyを触り始めて2週間ほどになりますが、ハッシュ、シンボル、キーワード引数まわりがエラーの源泉となっていました。
その中から、最近出会ったエラーの紹介をします。

Rubyのバージョン：**3.0.6**

:::note info
Ruby 3.1.0 以降は挙動が異なるようです。
:::
コメントより教えていただきました。@scivolaさんありがとうございます！

## キーワード引数の場合  

キーワード引数で受け取る場合、`multiply(x: , y: )`のようにキーワードだけ記入して、値は空にしておくことができます。
デフォルト値をつける場合はハッシュのように、値を書けばいいだけです。

```ruby:multiply.rb
# デフォルト値なし
def multiply(x: , y: )
    puts x * y
end

# デフォルト値あり
def multiply_default(x: 4, y: 5)
    puts x * y
end

multiply(x: 2, y: 3)  #=> 6
multiply_default      #=> 20
```

## ハッシュでのミス
その似通った見た目に引っ張られたのでしょう。
ハッシュでも同じことをしてしまいました。

```ruby
numbers = {x: , y: } #=> syntax error, unexpected ','
numbers[:x] = 6
numbers[:y] = 7

multiply(**numbers)
```

## ハッシュの初期化  

ハッシュの初期化は`hash = {}`か、入れておきたい値がなくともnilを使って`hash = {x: nil, y: nil}`のように値が必要です。　　

```ruby
numbers1 = {}
numbers1[:x] = 6
numbers1[:y] = 7

numbers2 = {x: nil, y: nil}
numbers2[:x] = 8
numbers2[:y] = 9

multiply(**numbers1) #=> 42
multiply(**numbers2) #=> 72  
```

## おわりに  

`:`の存在にずいぶん翻弄されましたが、やはり使っていくうちに慣れてきました。　　
手を動かしてRubyに慣れていきたいと思います！
【Homebrew】brewコマンド一覧

## `update`

Homebrew 自体を更新します。

```zsh
brew update
```

特定のコマンドを実行した際に`HOMEBREW_AUTO_UPDATE_SECS`の間隔で自動実行されます。
デフォルトは300秒です。
`brew update`が実行されてから300秒経過すると`brew install`, `brew upgrade`, `brew tap`などの前に自動実行されます。

```zsh:ターミナル
$ brew upgrade
Running `brew update --auto-update`...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
```

自動実行を無効にする場合には`HOMEBREW_NO_AUTO_UPDATE`を設定します。

## `install`

formula をインストールします。

```zsh
brew install formula名
```

MacOSのアプリケーションをインストールする際には以下のように実行します。

```zsh
brew install --cask cask名
```

## `upgrade`

インストールされている formula を更新します。

以下のように実行するとインストールされているすべての formula が更新されます。

```zsh
brew upgrade
```

特定のformulaを更新する場合は以下のように formula 名を指定します。

```zsh
brew upgrade formula名
```

## `outdated`

更新可能な formula の一覧を表示します。

```zsh
brew outdated
```

## `list`

Homebrewでインストールした formula の一覧を表示します。

```zsh
brew list
```

## `info`

formula に関する情報を表示します。

```zsh
brew info formula名
```

## `deps`

formula の依存関係を表示します。

以下のように実行するとインストールされている全 formula の依存関係をツリー表示します。

```zsh
brew deps --tree --installed
```

また以下のように実行すると特定の formula の依存関係をツリー表示します。

```zsh
brew deps --tree formula名
```

## `uninstall`

formula をアンインストールします。

```zsh
brew uninstall formula名
```

## `autoremove`

他の formula の依存関係としてのみインストールされ不要となった formula をアンインストールします。

```zsh
brew autoremove
```

`HOMEBREW_AUTOREMOVE`を設定すると`brew cleanup`, `brew uninstall` を実行した際に`brew autoremove`が自動実行されます。
また`HOMEBREW_CLEANUP_MAX_AGE_DAYS`間隔の`brew cleanup`定期実行時にも自動実行されます。
ただし`HOMEBREW_NO_INSTALL_CLEANUP` が設定されている場合には`brew cleanup`が定期実行されないため自動実行されません。

## `cleanup`

formula や cask のキャッシュを削除します。
またインストールされている formula の古いバージョンを削除します。
デフォルトでは120日以上前のダウンロードをすべて削除します。
この日数は`HOMEBREW_CLEANUP_MAX_AGE_DAYS`で変更できます。

以下のように実行するとすべての formula や cask に対して`cleanup`します。

```zsh
brew cleanup
```

`brew install`, `brew upgrade`, `brew reinstall` を実行すると自動実行されます。
自動実行の間隔は`HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS`で設定できます。
デフォルトは30日です。
自動実行を無効にする場合には`HOMEBREW_NO_INSTALL_CLEANUP`を設定します。
特定の formula のみ無効にする場合には`HOMEBREW_NO_CLEANUP_FORMULAE`を設定します。

## `doctor`

システムに問題がないかチェックします。

```zsh
brew doctor
```
Blender 初歩のショートカット

# はじめに
  Blenderを始めるにあたってショートカットを覚えてないとやってられません.
そのため必須級に覚えるべきのショートカットを上げていきます.
前提として各種モードなどの知識があるものとします.
とりあえず何をするにも重要なものをまとめ, その後種類に分けていきます.
ここでは基本的に環境が違っても変わらないものを上げていきます.

# 環境
blender 3.3.1

# この記事でのキーコンビネーション
shift + a -> S-a
Shift + a + b -> S-a-b
Ctrl + a -> C-a

# 重要なもの

### 共通
| ショートカット | 機能 |
|:---:|:---:|
|g|選択物の移動|
|r|選択物の回転|
|x|選択物の削除|
|z|シェーディングの変更|
|C-z|一つ前に戻る|

### オブジェクトモード
| ショートカット | 機能 |
|:---:|:---:|
|S-a|オブジェクトの追加|

### 編集モード
| ショートカット | 機能 |
|:---:|:---:|
|C-r|ループカット|
|e|押し出し|

# 共通
## 一覧
| ショートカット | 機能 |
|:---:|:---:|
|g|選択物の移動|
|r|選択物の回転|
|x|選択物の削除|
|z|シェーディングの変更|
|S-d|選択物のコピー|
|C-z|一つ前に戻る|

## g
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627149/dae59fae-fdf3-ecb2-2b8a-e93fcc338639.png)
選択したものを移動させます.
オブジェクトモードではオブジェクトを,
編集モードでは頂点, 辺, 面などを移動できます.

## r
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627149/da7c1993-ae8b-900d-ace0-5677bff4299f.png)
選択したものを回転させます.
オブジェクトモードではオブジェクトを,
編集モードでは辺, 面などを回転できます.

## x
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627149/b002ae57-46bb-dd20-e126-55c49a0ad834.png)
選択したものを削除します.
オブジェクトモードではオブジェクトを,
編集モードでは頂点, 辺, 面などを削除できます.

## z
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627149/d56b4871-ed10-06cc-0b78-cd385b0f00a1.png)
全体のシェーディングを変更します.
ソリッドはテクスチャなしですべて灰色で表示するモードです.
レンダーは照明を含めた最終的な仕上がりを表示するモードです.
マテリアルプレビューは照明を除いたテクスチャを表示するモードです.
ワイヤーフレームはオブジェクトの辺だけを表示するモードです.

## Shift - d

## Ctrl - z
一つ前に戻ります.

# オブジェクトモード
## 一覧
| ショートカット | 機能 |
|:---:|:---:|
|S-a|オブジェクトの追加|

## Shift - a
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627149/1abe7580-d157-cb3f-d11e-e07cda2292ba.png)
オブジェクトを追加します.


# 編集モード
## 一覧
| ショートカット | 機能 |
|:---:|:---:|
|C-r|ループカット|
|e|押し出し|
|C-b|ベベル|

## Ctrl - r
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627149/a09170b1-48a2-6bb2-8b06-87645ab0f61f.png)
ループカットです.
ぐるっと囲むようにカットして頂点と辺を追加します.
これは四角のメッシュにのみ適応されます.

## e
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627149/247e107e-56cf-09d4-e65e-c004235442c9.png)
選択した頂点, 辺, 面を押し出します.
新しい頂点, 辺, 面を作り出します.

## Ctrl - b
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627149/1afe066c-924a-c4f6-de47-c4865131f463.png)
ベベルです.
画像のように角を丸めるような処理をできます.

# 最後に
足りないと思う点や相違のある点はコメントをいただければ適宜修正いたします.
Ubuntu22.04 で SDカードをコピーする

# はじめに

RaspberryPi4 のSDカードがなんか死んでる気がする。。。

そうだとりあえず、SDカードのコピーしてみよう

# 環境

```terminal
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.2 LTS"

$ cat /etc/os-relase
PRETTY_NAME="Ubuntu 22.04.2 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.2 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

$ lsusb
 :
 :
Bus 001 Device 008: ID 05e3:0751 Genesys Logic, Inc. microSD Card Reader
 :
 :

$ lsblk
 :
 :
sda           8:0    1  14.9G  0 disk 
├─sda1        8:1    1   256M  0 part 
└─sda2        8:2    1  14.6G  0 part
 :
 :
```

# まずは元のSDカードのイメージを読み込み

```terminal
$ sudo dd if=/dev/sda of=sdcard_backup.img bs=4M status=progress
```

# 新しいSDカードにイメージを書き込み

```terminal
$ sudo dd if=sdcard_backup.img of=/dev/sda bs=4M status=progress
$ sudo sync
```
# ファイルシステムのチェック

```terminal
$ sudo lsblk -f
 :
 :
sda                                                                                        
├─sda1      vfat     FAT32 system-boot ****-****                                           
└─sda2      ext4     1.0   writable    ********-****-****-****-************ 
 :
 :

$ sudo dosfsck -a /dev/sda1
fsck.fat 4.2 (2021-01-31)
Reclaimed 90 unused clusters (46080 bytes) in 1 chain.
Dirty bit is set. Fs was not properly unmounted and some data may be corrupt.
 Automatically removing dirty bit.
Free cluster summary wrong (238368 vs. really 238278)
  Auto-correcting.

*** Filesystem was changed ***
Writing changes.
/dev/sda1: 747 files, 277912/516190 clusters

$ sudo e2fsck -f /dev/sda2
 :
 :
writable: ***** ファイルシステムは変更されました *****
writable: 129730/947776 files (0.2% non-contiguous), 1145114/3835131 blocks
```

# さいごに

かんたんでしたね
テストで1~9999の穴あきデータを埋めた備忘録（oracle)

結合テストを行うために検証用のＤＢにデータを登録した。
使用DBはoracle。触ったのは初めてだったので調べながらsqlを書いた。
アプローチを誤って？時間がかかってしまったので備忘録として残す。

＜結論＞
・データの穴埋めを行うにはinsertにnot existを組み合わせる。
　またinsert intoの後に行うselectには固定値を入力する。

＜前提条件＞
・IDを1~9999全て抜けが無い状態でDBに登録する必要がある（PKで重複不可）
・他のカラムは固定値を登録する（任意の値でOK）
・本番環境からマスクデータ化して検証環境に移したデータがあるため、虫食い状態となっている。
（例えば１、２、４、５、６のように）
・既に入っているデータを消すのはNG

＜最初考えたこと＞
insertで1~9999全部埋めよう

→PKの重複チェックでsql実行不可。さて困った…

＜誤ったアプローチ＞
cursor fetchで１行ずつ存在するデータを取得して、存在していたらinsertしない
→取得まではできた。この後どうやって条件分岐を書こう・・・？
普通にロジック組めそうだけど上手く書けない悔しい

＜上手くいったアプローチ＞
ロジックは下記
①9999回ループを行う。オラクルではFOR i IN 1..9999 LOOP。
②DBにiの値がIDとして存在しない場合、insertを行う。
→insert intoにselectとnot existを組み合わせて行う。

組み合わせるとこんなsqlになった。
FOR i IN 1..9999 LOOP
insert into DB名 カラム1, カラム2
select i,'hoge'from dual
where not exists (select カラム1 from DB名 where カラム1 = i);
END LOOP;

→無事に1~9999が連番で存在するDBを作成することができました。

書き終わってみるととても単純な内容ですが、考えているときはすんなりと浮かばなかった。
selectで固定値を取得できることや、その内容をinsertすると便利なことを今回知ることができました:)

＜参考にしたサイト様＞

・オラクルでループどう書くか
https://www.shift-the-oracle.com/plsql/for-while-loop.html

・存在しない判定をどうやるか
https://oreno-it.info/archives/2401

・固定値を入れる方法
https://qiita.com/kazuhei/items/60d8366b53e6ca8ef28a

初めて書いたので、不適切な内容等ございましたら申し訳ございません。
ご指摘いただけた場合、随時確認させていただきます。
【Python】pyautogui入門 -Kindleのハイライトを削除してみる-

# 概要

デスクトップのKindleアプリで、選択した本のハイライトと注記を削除する。

# 目的

もう一度読みたくなった本で、以前のハイライトや注記が目につくとなんか萎えたため。
それと新鮮な気持ちで読みたいため。

実装方法について、Seleniumで実装しようと思ったが、慣れている画像認識を使用した。

# ソースコード

``` python
import pyautogui as pgui

def locate_check(image_path : str) -> tuple:
    locate = pgui.locateOnScreen(image_path, grayscale=True, confidence=0.7, region=(3337,595,417,306))
    return locate

def image_locate_click(image_path : str) -> tuple:
    locate = locate_check(image_path)
    x, y = pgui.center(locate)
    pgui.click(x, y, duration=0.5)
    return (x, y)

def main():

    tyuuki = "./tyuukisakujo.png"
    highlight = "./hairaitosakujo.png"

    pgui.hotkey('alt', 'tab')

    while True:
        try:
            image_locate_click("./option.png")
            
            if locate_check(tyuuki):
                image_locate_click(tyuuki)
            elif locate_check(highlight):
                image_locate_click(highlight)
            else:
                pass
            pgui.press('home')
        except:
            break

if __name__ == "__main__":
    main()

```

# 実行方法

alt + tabでKindle(PC版)に移動できる状態にしてください。

実行後は遷移して画面右側のオプションボタン(・・・みたいなやつ)をクリックし、ハイライトまたは注記を削除します。

途中のhome押下はハイライトしている箇所が多いと、指定の座標範囲に収まらないため実施しています。

# 注意点

regionで指定している座標は、筆者のPCが4Kモニターを使用しているため、他のサイズをご使用の際は適宜変更してください。

# その他

github → https://github.com/Suntory-Y-Water/HighlightDelete
【初心者向け】色んなRubyの修飾子（備忘録）


# Rubyの修飾子でシンプルなコードを書こう！

Rubyには、条件分岐や繰り返し処理の結果に応じて、ある処理を実行するという場合に、修飾子を使ってコードをシンプルにすることができます。

Rubyの修飾子は、if、unless、while、until、for、next、breakの後に書かれ、行末まで実行する条件が満たされている場合に実行されます。以下は、基本的な構文の例です。


# if
```
puts "成人です" if age >= 20
```
# unless
```
puts "未成年です" unless age >= 20
```
# while
```
i += 1 while i < 5
```
# until
```
i += 1 until i == 5
```
# for
```
puts i for i in 1..5
```
# next
```
next if i == 3
```
# break
```
break if i == 3
```

# ifを使った繰り返し処理
```
array = [1, 2, 3, 4, 5]
array.each { |i| puts i if i.even? }
```

# unlessを使った条件分岐
```
puts "Hello" unless false
```

# まとめ

修飾子を使うと、コードをシンプルに書くことができ、読みやすくなります。

また、処理の実行を条件式の前に書くことで、コードの見通しも良くなります。

しかし、修飾子を過剰に使いすぎると、コードが読みにくくなる可能性もあるそうなので使い時が大事そうですね。

Rubyの修飾子について簡単に解説しました！
SQL Serverのインスタンスが起動していない場合の対処法（VB.NET）

# error: 26というエラーが発生した
アプリケーションでログインをしようとすると、エラーが発生してしまい、正常に使用することができなくなった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/dfe6b5d6-ef15-feea-e0c1-316b605dd24d.png)
**エラー内容**
```
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)
```

# 原因
**SQL Serverのインスタンスが起動していない**
デバックし、調査をしたところ、SQL Serverへの接続で失敗していることが分かった。その後、調査した結果、SQL Serverのインスタンスが立ち上がっていなかったことが原因だった。（なぜ、インスタンスが停止していたのかは、原因不明）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/53c5bfad-9239-8a99-5403-751244d9650e.png)
**※今回の記事の内容に至っては、インスタンスが起動していないことが原因でしたが、ほかの要因によってこのエラーが発生する場合もあるかもしれませんので、ご注意ください**

# 対処法
1. Sql Server Configuration Manager(SQL Server構成マネージャー)を起動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/591432a0-34bf-4c5d-db2c-019596f302a4.png)
2. 対象のSQL Serverを起動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/d77e5f43-f3a9-b5f4-8046-626bc3ffd0f5.png)

# インスタンスを起動した結果
正常にアプリを使用することができるようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/4324beca-a99d-3f7a-cda9-b6484aa9b818.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/e42dafc1-c435-0e9a-f33d-f5cd64b11999.png)

# 注意事項
- この記事では、SQL Server、SSMS、visual studioを使用しているので、試してみたい方は事前に準備が必要です。

# この記事は誰向けの記事か？
- エラーで困っている人向け

# 環境
- OS：Windows10
- [SQL Server](https://www.microsoft.com/ja-jp/sql-server/sql-server-downloads)
- [SQL Server Management Studio（SSMS）](https://learn.microsoft.com/ja-jp/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver16):v19.0.2
- [visual studio 2022](https://visualstudio.microsoft.com/ja/vs/)

# 本記事における注意事項
- 本記事は、備忘録としてまとめたものになります。
- 他の方の参考になる可能性も踏まえて、一般公開も行なっております。
- また記載内容はすべて、正しい内容が記載されているとは限りません。
- 誤った内容を見つけた場合は、ご指摘をお願いいたします。