OmniAICreator/Qiita-1.07M huggingface dataset:
同じディレクトリ構成のままコピーする

```python
import shutil
import os


input_path = "C:/Users/hoge/Desktop/プログラミング/python/プログラム/sample02/module03"
input_path_list = input_path.split("/")

output_path = "./output"

for path in input_path_list[input_path_list.index("python") :]:
    output_path = os.path.join(output_path, path)

try:
    shutil.copytree(input_path, output_path)

except Exception as e:
    print(e)

```
SkyOfficeをDockerで導入

# はじめに
SESでリモートしていると会社と関わる機会が少なく、なかなか社内のメンバーと接する機会がないため、バーチャルオフィスを導入してみようと思いOSSのバーチャルオフィスないかなと探したところSkyOfficeというものがあったので動かして見ました。

# SkyOffice

ゲームボーイアドバンスのポケモンみたいなUIでコミュニケーションが取れます。
無料なのがすごい。

**機能**
- お互いのキャラが近づくとビデオ通話
- チャット
- ホワイトボード
- PCの画面共有

どんな画面かなどは公式のREADMEを見てください。

https://github.com/kevinshen56714/SkyOffice

## 構築

社内システムとしてサーバー上に構築するためDockerで動かします。

gitをcloneしてSkyOfficeフォルダ内にcompose.ymlを作成します。

```yml:compose.yml
services:
  server:
    image: node:20
    container_name: skyoffice-server
    working_dir: /usr/app/SkyOffice
    tty: true
    ports:
      - "2567:2567"
    volumes:
      - "./:/usr/app/SkyOffice"
    command:
      bash -c "yarn && yarn start"
  client:
    image: node:20
    container_name: skyoffice-client
    working_dir: /usr/app/SkyOffice/client
    tty: true
    ports:
      - "80:5173"
    volumes:
      - "./:/usr/app/SkyOffice"
    command:
      bash -c "yarn && yarn dev --host"

```

`docker　compose up -d`を実行すれば`http://localhost`でログイン画面が表示されます。

## まとめ
Dockerの理解が浅かったためつまづきましたが、簡単に導入することが可能です。
必要なサーバーのスペックなどの情報は見当たらなかったため、触ってみて記事を更新したいと思います。

Docker Composeの設定について別の記事でまとめましたので、Docker Composeの設定内容を見たい方はこちらを参照ください。

https://qiita.com/boragi/items/8c401efa20de0c3510a4


## 参考サイト

https://diamond-f.co.jp/recruit/event/%E3%83%90%E3%83%BC%E3%83%81%E3%83%A3%E3%83%AB%E3%82%AA%E3%83%95%E3%82%A3%E3%82%B9%E6%A7%8B%E7%AF%89%E3%81%97%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/


こちらのサイトのdocker-composeはSkyOfficeフォルダと同階層に置いた時の設定が載っています。
Qiitaのクローンアプリを作成してアプリ開発体験を経験してみた

### はじめに
エンジニアとして技術力を磨きたいと思い、実際にアプリを設計から実装まで一貫して体系的に学習することを実践しました。
ただ、作りたいアプリがパッと思いつかなかったためQiitaを参考に必要な機能に絞ったクローンアプリを選択しました。

### 使用技術
案件では主に保守運用として調査タスクをメインとしているためコードリーディングは行いますが実装する機会は少ないため技術部分を深く理解できていないところがあるなと自分で感じることがあります。

そのため技術に関しては案件で利用しているrailsとnuxtを選択して実際にその言語で実装をしてみることによりベースとなる実装面での知識を深めていきたいなと思いました。
```
Ruby on rails 7.0.6
Nuxt 2.15.8
Mysql 8.0
Docker
```

### アプリ概要
Qiitaといえばエンジニアがアウトプットや質問を投稿できるプラットフォームですが、今回はアウトプットを投稿できる簡易的なTODOアプリに絞って開発をしていくことにしました。
```
- ログイン機能
 - ユーザー登録情報を元に認証し、ユーザー独自のユーザーエクスペリエンス（UX）を実現します。
- 投稿機能
 - ユーザーがマークダウン記法で記事を書くことができます。 
 -ユーザーは自身が登録した投稿内容を編集または削除することができます。
- 検索機能
 -キーワードやカテゴリを使用して記事を簡単に検索できます。
- いいね機能
 -記事に「いいね」をすることができ、自身が獲得した「いいね」の数はダッシュボードで確認できます。
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628968/9e74b735-0db9-db22-76f1-d13e1d692f6e.png)

### どのように開発を進めたか

#### タスク管理
notionでタスクボートを設けてタスク毎にチケットを作成し自分が何をすべきなのかを明確にして進めました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628968/1e6cd53a-fdbe-b738-f1d0-22f72b380fa9.png)


#### 設計フェーズ
要件定義から始め、DB設計や画面設計、開発規約の整備等も併せて行いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628968/7cd07dc3-2254-8b23-6e52-f65056d1e653.png)

#### 実装フェーズ
いきなり実装するのではなく必ず実装前にアウトラインを作成する事を行いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628968/65218b7e-864f-da30-a4e6-7ef3ce9ac092.png)

またPRのレビューに関してもセルフレビュー時にChatgptを利用して実装の良し悪しの確認を行っています。

```
#命令書:
あなたは、シニアエンジニアです。
以下の制約条件と入力文をもとに、 最高のコードレビュー結果を出力してください。

#レビュー箇所
記事の検索機能におけるrspecのテストコード

#制約条件:
・ジュニアデベロッパーに対してレビューが分かるようにお願いします。
・今回はrailsで{#レビュー箇所}。
・railsのお作法的におかしなところがないか重点的に見てほしいです。
・バグやアンチパターンの有無検証。
・コードの可読性やパフォーマンスに関する改善提案。

#入力文:
ここにコードを貼る

#出力例:
・良いところ
　・ここに良いと思うところを具体的に書く
・よくないところ
　・ここに良くないと思うことを具体的に、またコード例等を示しながら記載する

#出力文:
```

### おわりに
今回初投稿をさせていただきました！
本稿では作成したQiitaのクローンアプリの概要や進め方を中心にお伝えさせていただきました。
実際に自分でアプリを作成してみると一見動くから問題ないという実装でも、パフォーマンス面を考えると書き振りが良くなかったりなどの今まで触れてこなかった面の視野を広げることができ、非常に勉強になりました。

具体的に設計や実装面においての詳細的なアウトプットに関しては別途投稿でお伝えさせていただければと思いますのでよろしくお願いいたします。
エラーメッセージの読み方

エラーメッセージの読み方について解説します。

## 間違っているコード

```php
<!-- secondary -->
<aside id="secondary">
	<?php if (is_active_sideber('sidebar')) : ?>
		<?php dynamic_sidebar('sidebar'); ?>
	<?php endif; ?>
</aside><!-- secondary -->
```
今回は、単純な綴りの間違いでエラーコードを確認します。
意図的に`is_active_sideber`と記載。（正しくは `is_active_sidebar`）

## 表示されたエラーメッセージ


Fatal error: Uncaught Error: Call to undefined function is_active_sideber() in /Users/Desktop/PHP/dev/wp-content/themes/theme/sidebar.php:3 Stack trace: #0 /Users/Desktop/PHP/dev/wp-includes/template.php(810): require_once() #1 /Users/Desktop/PHP/dev/wp-includes/template.php(745): load_template('/Users/...', true, Array) #2 /Users/Desktop/PHP/dev/wp-includes/general-template.php(136): locate_template(Array, true, true, Array) #3 /Users/Desktop/PHP/dev/wp-content/themes/theme/index.php(54): get_sidebar() #4 /Users/Desktop/PHP/dev/wp-includes/template-loader.php(106): include('/Users/...') #5 /Users/Desktop/PHP/dev/wp-blog-header.php(19): require_once('/Users/...') #6 /Users/Desktop/PHP/dev/index.php(17): require('/Users/...') #7 {main} thrown in
/Users/Desktop/PHP/dev/wp-content/themes/theme/sidebar.php on line 3

（※少し改変して記載）


## エラーメッセージを解析する際に注目すべき重要な部分  

#### 1. エラーの種類とメッセージ

```
Fatal error: Uncaught Error: Call to undefined function is_active_sideber()
```

日本語訳は、「致命的なエラー： 捕捉されないエラー： 未定義の関数is_active_sideber()への呼び出し」です。

これは「致命的なエラー」であり、「定義されていない関数を呼び出そうとした」と説明しています。

#### 2. ファイルパスと行番号

```
/Users/Desktop/PHP/dev/wp-content/themes/theme/sidebar.php:3
```

このエラーが発生している具体的なファイルと行番号を示しています。

`sidebar.php:3` これはsidebar.phpファイルの3行目がエラーですよ。ということ。

#### 3. スタックトレース

```
Stack trace: #0 /Users/Desktop/PHP/dev/wp-includes/template.php(810): require_once() #1 /Users/Desktop/PHP/dev/wp-includes/template.php(745): load_template('/Users/...', true, Array) #2 /Users/Desktop/PHP/dev/wp-includes/general-template.php(136): locate_template(Array, true, true, Array) #3 /Users/Desktop/PHP/dev/wp-content/themes/theme/index.php(54): get_sidebar() #4 /Users/Desktop/PHP/dev/wp-includes/template-loader.php(106): include('/Users/...') #5 /Users/Desktop/PHP/dev/wp-blog-header.php(19): require_once('/Users/...') #6 /Users/Desktop/PHP/dev/index.php(17): require('/Users/...') #7 {main}
```
エラーが発生するまでの関数呼び出しの連鎖（スタックトレース）が示されています。ここでは、どのファイルと関数からこの問題のある関数が呼び出されたかが列挙されています。

スタックトレースは、特定のエラーが発生した際に、どのファイルや関数が関与しているかを詳細に追跡する手助けになります。

ちなみに`template.php(810)` の`810`は行番号です。

#### 4. エラーが「投げられた（発生した）」場所
```
thrown in
/Users/Desktop/PHP/dev/wp-content/themes/theme/sidebar.php on line 3
```
最後にもう一度、具体的にエラーが発生したファイル名と行番号が記載されています。

## 最後に
特に重要なのはエラーの種類とメッセージ、およびファイルパスと行番号です。これらを正確に読み解くことで、エラーの原因を特定しやすくなります。
Numpyのメモ（随時更新）

忘れがちなので個人的なNumpyのメモを残しておきます。
ちょっとずつ増やしていく
```python
>> import numpy as np
```

## 連続した数列を作成したい
```python
>> np.arange(10)

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
```

## 乱数を生成する
```python
>> from numpy import random # パッケージのインポート

>> random.rand() # [0, 1)の乱数を生成

>> random.randn() # 平均0, 分散1の正規分布に従う乱数を生成

>> random.normal(100, 1) # 平均と分散を指定して正規分布に従う乱数を生成、第1引数が平均、第2引数が分散

>> random.rand(5) # 長さ5(=shapeが(5, ) )の乱数の1次元配列を生成

>> random.rand(5, 5) # shapeが(5, 5)の乱数の2次元配列を生成

>> random.normal(100, 10, (5, 5)) # shapeが(5, 5)で平均100, 分散10の正規分布に従う乱数の2次元配列を生成

>> random.seed(seed=32) # seed値として整数を指定して、乱数を生成する
```

## ユニバーサル関数でよく使用するもの

[参考](https://docs.pyq.jp/python/pydata/numpy/universal_function.html)

### 最大値を取得する
```python
>> a = np.arange(10)
>> np.max(a)

9
```

## 行ごとor列ごとに関数を適用したい

```python
# aという配列に対して、行ごとにnp.maxを適用する
>> np.max(a, axis=1, keepdims=True)
```

## ノルムを計算する
```python
>> a = np.arange(10).reshape(3, 3) # 例として3行3列の二次元配列を用意

array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

>> np.linalg.norm(a) # aの行列ノルムを出す

14.283

>> np.linalg.norm(a, axis=0) # 列毎のベクトルノルムをとる

array([6.708, 8.124, 9.644])

>> np.linalg.norm(a, norm=1) # 行毎のベクトルノルムをとる

array([ 2.236,  7.071, 12.207])

>> np.linalg.norm(a, ord=2) # 各要素の2乗和の平方根でノルムを算出する、デフォルトは2

14.227

>> np.linalg.norm(a, ord=N) # 各要素のN乗和の平方根でノルムを算出する
```
TripleLTE_Ethernet_Gateway のソースコードを公開しました。

下記の記事で作成したファームウエアのソースコードを公開しました。

https://qiita.com/Akihiro-Sakaniwa/items/d03dbbdd7ca5ee363a6c

https://github.com/Akihiro-Sakaniwa/TripleLTE_Ethernet_Gateway



![TripleLTE_Ethernet_Gateway.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190537/5683f966-952d-237e-3f22-ca3d3fa7550c.png)

ご参考まで。


# 以上。
後追いだけど、AWS Bedrockをさわってみる

### はじめに

ずっとXで追いかけている[みのるんさん](https://qiita.com/minorun365 "みのるんさんのQiita")が最近Bedrockを扱うのにとても素敵な記事を出してくれたのでそれを行ってみる。

私はAWSサービスも基本のサーバーサービスくらいしか使ったことがないので、この記事にそってどのくらいできるかが楽しみ、、！

### 今回参考にする記事

AWSの生成AIで社内文書検索！ Bedrockのナレッジベースで簡単にRAGアプリを作ってみよう
https://qiita.com/minorun365/items/24dfb0ea3afde6ed0a56

### 実際に行ってみたときのメモ

#### 環境構築

- IAMアカウトの作成
AWSアカウントはすでに持っているので、IAMを改めて作ってみる。
人に任せてAWS CLIをさわってもらう際は、すでに権限を絞って任せているから安心できるけど、rootくらい強い権限のアカウントでマネジメントコンソールをさわってもらうってやっぱり危険だなって感じた。
　

- Cloud9の起動
レクチャーの記事では、デフォルト設定で問題ないと記載していただいた(優しい！)。
ボタン一つでこんな簡単に環境ができるのかと、EC2とは別の意味で感動を覚えました。
Chat機能があったり、repository機能があるなんて素晴らしい。

#### ナレッジベース作成編
ここで、注意書きもしてもらっているのに、Amazon Bedrockのサイドメニューに東京リージョンで「オーケストレーション」がないことで1時間近く溶かしてしまった。リージョン違いで、つくった環境消えたと思って探したことはあったけど、まさか1年越しにそれをやらかすなんて。

改めてCloud9も米国東部 (バージニア北部)で作成して、S3バケットもつくりなおしました。

#### モデル有効化編

この辺りは、実際に行ってみたら初めての用語と初めての操作ばかりでただただハンズオンしてました。ベースモデルって何？とか、プレイグラウンドとは？みたいなはてなが多く、手順通りにとりあえずやってみました。

単語については、今日の夜に調べて最下部あたりにメモしておきます。

実際の作業時間は、20分くらいです。
マネジメントコンソールに苦戦していた印象です。

#### アプリ開発編

ここは、もう感動です。
手順通りばんざい。

Webサービスとして、実際に行うならこのようにしていくんだろうなってのがわかったことは、とても嬉しかったです。

実際にコピペしないで手を動かして、記載していってみました。

### 実際に行ってみた感想

思ったよりも簡単で、この手順をみれば誰でもできそうなのがとてもいいところです。
費用面さえ解決できたら、もっといいサービスを提供できる足掛かりになりそう。

運用までもっていくのに、
1. 費用問題
2. S3バケットへのアップロード方法について
3. 管理方法について

をクリアする必要がありそう。


最後に、みのるんさんのXもQiitaもいつも参考にさせていただいてます。
ありがとうございます。

### 用語

- AWS Cloud9とは？
    ブラウザだけでコードの書き込み、実行、デバッグできるサービスで、VScodeがブラウザで操作できるってイメージをもったらいいらしい。
    また、リアルタイムでソースの変更が反映されるので共同開発もできるとのこと(IDE)。大規模な開発ならGitやDockerをつかったほうがいいかもしれないが、LPくらいの規模ならこれでいいかもしれない
ntpを使わずに時間を合わせてみた

# Pythonを使用してAPIから取得した日時情報でシステムの日付と時刻を設定する方法

## 背景
学校のセキュリティー関係でntpサーバに接続できなかった（なんでや）．なので，毎回```sudo date --set "2024-04-29 09:03:54"```のようにraspberrypiの日時を更新していたのだが，流石に面倒なので，APIサーバーから日時を取得して時間を合わせるようにしてみた．

## コード
以下のコードを適当なディレクトリに保存し,```.bashrc```やら```.zshrc```に```python3 ~/hogehoge.py```のように書けば，起動時に勝手に実行してくれると思います．

```python
import requests
import subprocess

# APIエンドポイント
url = "https://www.timeapi.io/api/Time/current/zone?timeZone=Asia/Tokyo"

# リクエストを送信してレスポンスを取得
response = requests.get(url)

# レスポンスのステータスコードを確認
if response.status_code == 200:
    # JSON形式のレスポンスデータを取得
    data = response.json()

    # 取得したデータを使用してシステムの日付と時刻を設定するコマンドを生成
    command = f"sudo date --set \"{data['year']}-{str(data['month']).zfill(2)}-{str(data['day']).zfill(2)} {str(data['hour']).zfill(2)}:{str(data['minute']).zfill(2)}:{str(data['seconds']).zfill(2)}\""

    # サブプロセスを使用してコマンドを実行
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output, error = process.communicate()

    # コマンドが正常に実行されたかどうかを確認
    if process.returncode == 0:
        print("コマンドが正常に実行されました。")
        print(output.decode())
    else:
        print("コマンドの実行中にエラーが発生しました:", error.decode())
else:
    print("データの取得に失敗しました:", response.status_code)
```
## 終わりに
同じように困っている人（多分いない）の参考になればと思います．間違え等ございましたら，コメントで教えていただけるとありがたいです．
FileZillaでファイルのダウンロードができないエラー(Could not open 致命的なファイル転送エラー)の備忘録

### 解決方法

①サイトマネージャー
②接続
③右側の詳細ボタン
④デフォルトのローカルディレクトリ
⑤参照

参照にダウンロード先の格納フォルダを指定
例えば、ダウンロードフォルダにダウンロードしたファイルを格納したいとします。
以下のようなパスになるはずです。
/Users/userid/Downloads

useridにはPCの名前が入ります。

これでダウンロードができるようになりました。

最後までお読みいただきありがとうございました。
ここは違う、ここはこの方が？等々ございましたらご指摘いただけますと幸いです。
ウォルステンホルム素数（Haskellで出力する）

こんにちは｜こんばんは。カエルのアイコンで活動しております @kyamaz :frog: です。


## はじめに
本稿は「[ウォルステンホルム素数（Wolstenholme prime）](https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A9%E3%83%AB%E3%82%B9%E3%83%86%E3%83%B3%E3%83%9B%E3%83%AB%E3%83%A0%E7%B4%A0%E6%95%B0)」を出力する処理を、Haskellで実装するShortエントリーです。すでに[ヴィーフェリッヒ素数を出力するエントリ](https://qiita.com/kyamaz/items/d550448562f07b9d75fb)をご紹介しましたが、本稿でも似たような処理をご紹介します。

::: note warn
紹介する処理は、非常に時間を要する処理です。お試しになる際には、お時間があるときをお勧めします。
:::

# ウォルステンホルム素数

ウォルステンホルム素数は、@tsujimotterさんのYouTubeでも紹介されています。

https://www.youtube.com/watch?v=xhvB2ohuKiQ

2007年時点では$10^9$までの範囲で調べられており、既知のウォルステンホルム素数は、$16843$と$2124679$のみです。

いつくかの同値の定義がありますが、二項係数による定義を次に紹介します。

:::note info
<dl>
<dt>ウォルステンホルム素数の定義</dt>
<dd>${}_{2p-1} C_{p-1} \equiv 1 \pmod{p^{4}}$ を満たす素数$p$
</dd>
</dl>
:::

ウォルステンホルム素数は無限個存在すると予想されており、また$x$以下のウォルステンホルム素数の個数は約$\ln{\ln{x}}$個と予想されておりますが、いずれも未解決問題です。

それでは、ウォルステンホルム素数をHaskellで出力する処理を作っていきましょう。
まずは、定義にコンビネーション（組合せ）が出てきますので、${}_n C_m$の計算を記述しましょう。${}_n C_m = \frac{{}_n P_m}{{}_m P_m}$であることを踏まえて実装します。

```Haskell:
-- 順列（permutation）の計算
ghci> perm n m | n<m = 1 | n<=0 = 1 | m<=0 = 1 | otherwise = foldr (*) 1 [(n-m+1)..n]
-- 組合せ（combination）の計算
ghci> comb n m | n<m = 1 | n<=0 = 1 | m<=0 = 1 | otherwise = perm n m `div` (perm m m)
```

次に、エラトステネスの篩を踏まえて素数列を実装します。

```Haskell:
-- 素数列 p
ghci> p=2:3:5:5#p;m#(a:b:x)=[n|n<-[a^2..b^2-2],(mod (n+1) 6)*(mod (n-1) 6)==0,gcd n m<2]++(m*b)#(b:x)
```

ウォルステンホルム素数の定義を素直に実装すると、次のようにウォルステンホルム素数列 `w` ができます。

```Haskell:
-- ウォルステンホルム素数
ghci> w=[n|n<-p, mod (comb (2*n-1) (n-1)) (n^4) == 1]
```

定義から実装を進めているだけですので、ここまではすぐに処理が終わります。さて、実際の計算を行ってみましょう。ウォルステンホルム素数は現在２個まで知られていますので、無邪気にウォルステンホルム素数列から最初の２つを取り出す処理として実行してみましょう。

```Haskell:
ghci> take 2 w
[16843
```

だいぶ時間はかかりましたが、最初の$16843$は出力されました。その次の値を待ちます。しかし、かなりの時間（数時間）放置しましたが、残念ながら$2124679$まで到達しませんでしたので、`Ctrl-C`で処理を中断しました。Wikipediaによると、この２つめの素数は、ほぼ20年間発見されなかったそうです。やはり手元のPCではなかなか酷な計算のようです。

## おわりに
ご一読いただきまして有り難うございます。
試しに以下も試しましたが、一晩おいても結果が出力されませんでした。チャレンジして出力されるようでしたら、教えて頂きたいです。

```Haskell:
ghci> mod (comb (2*2124679-1) (2124679-1)) (2124679^4)
```

最後に、本稿を記載するために検証したHaskell環境を記しておきます。お手元の環境で検証する際に、動作が異なるときには参考になるかもしれません。

<details><summary>本稿の環境</summary>

本稿のために使用した環境は以下となります。
macOS: Sonoma 14.4 (chip: Apple M1)
GHCup: 0.1.22.0
GHC: 9.6.4
</details>

（●）（●） Happy Hacking!
/""　＿＿""＼
古いフォーマットから新しいフォーマットにデータをコピーするVBA

# 利用シーン
でかいExcel表がある
入力欄が決まっている
入力欄にはセルの名前定義（ブックレベル）が設定されている
定期的に中身を一部書き換えて提出する
ところがたまにフォーマットが変わる
変わるたびに旧ファイルからのコピーが必要
しかもごくたまに一括コピーできないようなセル構造になる

# 何をするVBA？
旧ファイル（Latestのデータ）と新ファイル（テンプレート）の間で共通する名前定義を使ってデータをコピーする。

# ソース
```vb
Option Explicit

Sub start_proc()
Dim templateBookPath As String, inputBookPath As String, outputBookPath As String
Dim templateBook As Workbook, inputBook As Workbook

'設定項目の取得
inputBookPath = ThisWorkbook.Names("input_file_path").RefersToRange.Value
outputBookPath = Replace(inputBookPath, ".xls", "_" & Format(Now, "yyyymmddhhmmss") & ".xls")
templateBookPath = ThisWorkbook.Names("template_file_path").RefersToRange.Value
On Error GoTo NO_TEMP_BOOK
Set templateBook = Workbooks.Open(templateBookPath)
On Error GoTo NO_INPUT_BOOK
Set inputBook = Workbooks.Open(inputBookPath, 0, True)
On Error GoTo 0

'テンプレートの名前ループ
Dim tName As Name
Dim i As Long
For i = 1 To templateBook.Names.Count
    Set tName = templateBook.Names(i)
    tName.RefersToRange.Value = getValFromName(inputBook, tName.Name)
Next

'For Each templateBook.Names In tName
'    tName.RefersToRange.Value = getValFromName(inputBook, tName.Name)
'Next

'保存とブッククローズ
templateBook.SaveAs outputBookPath
templateBook.Close False
inputBook.Close False

Exit Sub
NO_TEMP_BOOK:
MsgBox "コピー先のテンプレートファイルの指定が正しくありません"

Exit Sub
NO_INPUT_BOOK:
MsgBox "コピー元のファイルの指定が正しくありません"

End Sub


Function getValFromName(wb As Workbook, nm As String) As Variant
    On Error GoTo Err
    Dim ret
    ret = wb.Names(nm).RefersToRange.Value
    Debug.Print nm & ": " & Left(ret, 10)
    getValFromName = ret
Exit Function
Err:
    Debug.Print nm & ": 対象の名前がありません"
End Function

```

# 一緒に使うやつ
[セルの値をセルの名前にしてくれるVBA](https://qiita.com/westdepth/items/317d85fa2df5e0bd7b6f)
iOSのPrivacy ManifestsのNSPrivacyTrackingDomainsに記載するドメインの調べ方

Google AdMobやApplovin Maxといったサードパーティのライブラリが接続しているトラッキングドメインを調べてPrivacy MainifestsのNSPrivacyTrackingDomainsに記載する手順です。


## 環境
Xcode 15.3

## 参考
[WWDC 2023: Get started with privacy mainifests](https://developer.apple.com/videos/play/wwdc2023/10060/?time=399)

## 手順
#### 1. Xcodeでプログラムをデバッグ実行します。
#### 2. Xcodeのナビゲータバーでデバッグナビゲーターを選択し、Networkを選択します。
![スクリーンショット 2024-04-29 10.03.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362719/0e88c383-9c88-c38f-7867-5f51d86a87d1.png)

#### 3. Networkの画面で[Profile in Instruments]をクリックします。
![スクリーンショット 2024-04-29 10.04.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362719/064f2778-05b3-25d5-f4ab-54be1aeb8c74.png)


#### 4. App network connectionsの画面が表示されるので[Points of Interest]を選択します。
![スクリーンショット 2024-04-29 10.06.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362719/271f9cef-1b9e-d58f-3b82-81919cd8aaf3.png)


#### 5. [Points of Interest]の[Start message]にNSPrivacyTrackingDomainsに記載する必要があるドメインが表示されますので、全てメモします。
![スクリーンショット 2024-04-29 9.56.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362719/3bd34eee-4124-d96a-0fdc-98f90044b6d7.png)


#### 6. メモしたドメインをPrivacy ManifestsのNSPrivacyTrackingDomainsに記載して完了です。
![スクリーンショット 2024-04-29 9.58.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362719/187d361e-bf20-47ba-0518-37792f348abe.png)

```PrivacyInfo.xcprivacy
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>NSPrivacyTrackingDomains</key>
	<array>
		<string>g.doubleclick.net</string>
		<string>googleads.g.doubleclick.net</string>
	</array>
    ---------- 略 ----------
</dict>
</plist>
```
Go言語について

# Go言語についての概要と学習内容について
go言語を勉強にするにあたり、ますはgo言語についての概要をまとめていく
調べてヒットした特徴をコピペし、それぞれの感想を書いてみた

### 概要
・シンプルで読みやすい構文: Go言語は、C言語のような伝統的な構文を持ちながら、冗長さを排除し、シンプルで読みやすいコードを書くことができます。
→まあ分かる

・効率的な並行処理: Go言語は、ゴルーチン（Goroutine）とチャネル（Channel）という仕組みを使って並行処理をサポートしています。これにより、軽量で効率的なスレッドの生成と通信が可能になります。
→並行処理に関する知見が不足しているため正直ぱっとイメージが沸かない（要調査）

・静的型付けと型推論: Go言語は静的型付け言語ですが、変数の型を推論する機能も持っています。これにより、型の記述が簡潔になります。
→いいね

・ガベージコレクション: Go言語はガベージコレクションをサポートしており、メモリ管理を開発者が手動で行う必要がありません。これにより、安全で信頼性の高いコードを書くことができます。
→いいね

・クロスプラットフォーム: Go言語は、Linux、Windows、macOSなどのさまざまなプラットフォームで動作します。また、CPUアーキテクチャにも対応しています。
→へー（正直あまり恩恵がわかっていない、、）（要調査）

・豊富な標準ライブラリ: Go言語には豊富な標準ライブラリが含まれており、ネットワーク、HTTP、JSON処理、暗号化などのさまざまな機能を提供しています。
→いいね

・ツールのサポート: Go言語には、コードのフォーマット、静的解析、テスト、ドキュメント生成などをサポートする豊富なツールがあり、開発者の生産性を高めます。
→いいね

といった感じだった。
いいことばかり書いてあるようだったのでデメリットがないかも調べてみた

#### デメリット
・~~ジェネリクスの不足: Go言語は、ジェネリクスのサポートが限られています。これは、汎用的なデータ構造やアルゴリズムを書く際に制約をもたらす場合があります。ただし、将来のバージョンで改善される可能性もあります。
→そんな気にしなくてよい？（筆者がジェネリクスのパワーを理解できていないから思うだけかも、、）~~
→ジェネリクスはすでに実装済み(v1.18以降）（追記：2024/4/29）

・静的解析ツールの不足: 一部の開発者は、Go言語向けの静的解析ツールが他の言語に比べて少ないと感じるかもしれません。これにより、一部のエラーや問題を早期に検出するのが難しい場合があります。
→大規模だと困りそう

・速度よりもメモリ効率: Go言語は一般的に高速ですが、他の言語と比較してメモリ効率が低い場合があります。これは、ガベージコレクタのオーバーヘッドやランタイムの特性によるものです。
→ざっくりしすぎてよく分からない。というかメモリ効率についてちゃんと勉強していないからよくわからない。。（今後勉強するかも）

・成熟度とエコシステムの不足: Go言語は比較的若い言語であり、一部の成熟したエコシステムやライブラリが他の言語と比較して少ないことがあります。しかし、この点はGoの急速な成長と共に改善されつつあります。
→じゃあ早めに手を付けておこう。。

・学習曲線: Go言語の構文やコンセプトは比較的シンプルですが、新しい開発者にとっては学習曲線があるかもしれません。特に、並行処理の概念やチャネルの使用方法など、独自の機能を理解するのに時間がかかることがあります。
→まさにその通りで並行処理の概念やチャネルの使用方法は理解しきれていなそう。。

上記のようになったが
これから学習していくにあたり、学習コストは高くなりそうだが価値はありそうだと感じた。（goを使わないにしてもCS的な意味合いで）

### 学習順序
以下の順で学習していく
①基本構文の理解: Go言語の基本構文やデータ型、変数、制御構造などの基本的な要素
②関数とパッケージ: 関数の定義や呼び出し、パッケージの作成やインポートなど、Go言語での関数とパッケージの基本的な使い方
③データ構造とコレクション: 配列、スライス、マップなどのデータ構造やコレクション
④ポインタとメモリ管理: ポインタの概念やメモリ管理
⑤並行処理とゴルーチン: ゴルーチンやチャネルを使った並行処理の概念
⑥エラーハンドリング: エラーハンドリングの方法や、エラーを適切に処理する技術
⑦テストとデバッグ: ユニットテストや統合テストの書き方、デバッグの方法など、テストとデバッグの基本的な技術
⑧標準ライブラリの活用: HTTP、JSON、暗号化、データベース等活用する方法
⑨実践的なプロジェクト: 実際に作ってみる

以下をモチベーションに勉強していく
・若い言語ができるとかっこよい
・単価アップ（銭ゲバです。。）
・名前が好き（これは筆者が北〇子様の回胴機に脳を焼かれてるからかもしれませんが ﾍﾟｶｯ）

不純な動機しかありませんが単純におもしろそうだなと思っています。
どこまでやれるかわかりませんが頑張ってみます。
Salesforceでフローを作成しよう～数式項目の値の変更により選択リストの値を変更する方法

　本橋孝昭です


 今回Salesforceフローで「数式項目の値の変更により選択リストの値を変更する方法」をご紹介します

 今回はこちらの記事で作成した数式項目の値を用います


https://qiita.com/Takaa/items/0eaa4677813a9f884b98

 ・8以上なら評価が「Hot」
 ・4以上7以下なら評価が「Warm」
 ・3以下なら評価が「Cold」
 という項目更新のフローを作成します


## フロー内容

実際のフローの内容はこちらになります

![001フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c9d2b4f3-09b0-4468-5e85-61cd59443607.png)


なお開始条件の数式は画面からは見にくいですが以下となります

>OR(
ISNEW(),
ISCHANGED({!$Record.test1__c}))


![002フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/e5e3a613-c76b-3a21-46b0-06f6abfbb221.png)
![003フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/1694b7cb-f3a2-401a-c2d0-73301b9f5dc9.png)
![004フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/04786b36-c79d-3f12-9bcc-85bbd1a99ad7.png)
![005フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/fc5d3f98-5eb6-9bbf-695d-f446ae5bc997.png)
![006フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/8a1a5920-64d4-4ea5-d83f-3eaad8b0ecc9.png)
![007フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/e28e6e09-22f7-539f-fe9b-a16a96809756.png)
今後の勉強内容について(React + Go)

　知人からホームページ作成を依頼されており、その中でブログの機能も追加してほしいとのことから興味があったgo+ reactで作成することにした。
　こちらは無料で提供するかわりに時間がかかってもよいと言われているのでお言葉に甘えてじっくり調べながら作成していく。
 　goもreactも一旦は参考書を読んでいるがあまり身についていないような気がしているため備忘としてまとめていく。
３日坊主にならないよう気を付ける。。
CODESYS アラームのLATCH変数


<h1>CODESYSで、仮想のサーボを使ったCNCを作っています。

仮想サーボで遊べるコード（プロジェクト）は公開予定です。
CODESYSの学習が（かなり）出来ると思います。必要な方いたらお知らせください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408008/37b57392-2e26-7c4a-303c-07ffa88e2ca4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408008/5ba1d557-7d8d-db76-0ec3-63ab4af9f566.png)

EtherCATのサーボをつないで動かせたらな、と思っていますが、サーボモータや機械がないので、実用になるのかわっぱり分かりません。


<h1>CODESYSのアラームとLATCH変数

CODESYSのアラームで、CNC関連の全アラームメッセージを登録するのは面倒なので、必要に応じてLATCH変数にエラーメッセージを入れて処理をするようにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408008/a257ae33-1b8f-3807-86b7-90d2b3abd891.png)

<h2>LATCH変数を使うとおかしな異常が時々発生

ところが、時々、アラームメッセージが１文字しか表示されなかったりします。
そのエラーメッセージの変数をVISUで表示させると、ちゃんと表示されます。

<h2>調査 -- 原因は SMC_ErrorString

どういうケースでおかしくなるか、調べてみました。
・アラームのCLASSかな？　CLASSは関係なかった。
・アラームの文字に変な文字がはいっていた？　問題なかった。

トレースしてみたら、SMC_ErrorStringで取ってきて表示させている箇所が問題ありそうでした。
エラーコードだけにしてみたら問題ありません。

しかし、エラー表示には、SMC_ErrorString使いたくなるのが、義理人情ってものではないでしょうか！

<h2>対応方法

とりあえず、文字列ではなく、エラーコードだけを表示するようにしたら、うまくいきました。

CNC関連のアラームは、EtherCATのリアルタイムタスク内で発生処理（フラグやメッセージのセット）をしているからかもしれません。SMC_ErrorStringは別のタスクで処理されるのかもしれません。（時間がかかるためか？）

異常発生のメカニズムはちょっとよくわからないので、他の方法もあるかな、とは思いますが、アラームとLATCH変数の挙動で悩んでいる方の参考になりましたら幸いです。

<h2>追記

EtherCATのリアルタイムスレッド以外でも、SMC_ErrorStringをLATCH変数で使ったらおかしくなりました。LATCH変数で使うとおかしくなるので、原因の文字列を含むものをALARM HISTORYで、という考えは上手くいかないようです。
Git/Githubの個人的覚書

個人的にGit/Githubで四苦八苦したことを備忘録メモとして継ぎ足していきます。

# Authentication Error
`push`や`ssh -T git@github.com`を実行しても、認証エラーでIDやパスワードすら打たせてもらえない。
ネットで検索しても解決しないので、GithubサイトにてSSH keysに登録していた公開鍵が古かったのが原因だった。
削除したらすんなりうまくいった。

## 手順
1.ブラウザでGit Hubにログイン
2.自分のアイコン > Settings > SSH and GPG Keys にアクセスして期限切れの鍵を削除
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588352/c1e0a623-9344-a118-a287-1081d19df820.png)

3.ローカル側の端末で下記手順で鍵を作成して公開鍵の中身をクリップボードにコピーする

```shell:鍵作成コマンド実行
$ ssh-keygen -t rsa -b 4096 -C "登録したメールアドレス"
Generating public/private rsa key pair.
```

```shell:鍵を作成するパスを聞かれたらそのままEnterキーを押下
Enter file in which to save the key (/c/Users/<home directory>/.ssh/id_rsa):
```

```shell:パスフレーズを入力※確認のため同じパスフレーズを2回入力する
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```

```shell:公開鍵の中身をクリップボードに貼り付ける
$ cat /c/Users/<home directory>/.ssh/id_rsa.pub
# ssh-rsaから鍵生成時に設定したメールアドレスまで全てコピーする
ssh-rsa sawklaieAABBASDAsdfawseklsadflkjas ～中略～ wai;AAaeck3le2093== "登録したメールアドレス"
```

4.ブラウザのGithubサイトに戻って、`New SSH key`ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588352/d7681270-317a-341a-8a7f-4aa65b12aa26.png)

5.`Title`に判別がつくように入力
6.`Key`にクリップボードに貼り付けた公開鍵を貼り付ける
7.`Add SSH key`ボタンをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588352/e5b9b4d4-091c-77e2-d8b1-f74e80444139.png)

8.ローカル側の端末にて下記コマンドを実行する
```shell:ssh接続テストを実行
$ ssh -T git@github.com
```

9.手順3.で設定したパスフレーズを入力して下記メッセージが出れば成功
```shell:パスフレーズを入力
Enter passphrase for key '/home/yutaka/.ssh/id_rsa':
Hi Utk-Ghub! You've successfully authenticated, but GitHub does not provide shell access.
```

# WindowsのPowershellでGitを使うと文字化け
大人しく、Git Bashを使うこと。
sshコマンドなども既に配備されており、別途Windowsにsshをインストールする必要はない。
変なtweet製造機

2007/12/13にとある呟きが投稿されました。以下のようなものです。
```
tdetyttstttettdeshhhhhhh h ilmmHttttttttat oi tbi aaaaaaaaa          o
```
一見すると何の変哲もない文字列に見えますが、よく見ると違和感っぽいものが浮き彫りに…。
なんと…全く意味不明な英字の羅列なのです!
**ひいいいええええええっ!**
恐ろしく恐ろしい怪文です!
そして更に奇妙な事に、文字`a`、`h`、`t`は連続する傾向にある点も気になります。一体誰が何の目的でこんな物を作り出してしまったのでしょうか?
解読するのは骨が折れそうです。暗号解読の専門家の栗原さんに相談したいくらいです。


## BWT
同じ文字が連続するという変換と言えば、圧縮力を磨いている読者ならピンくるかもしれません。そう、あの有名なBurrows Wheeler Transform(BWT)です。
しかしその逆変換には復元情報が必要となります。元の文字列を見てもそれらしきものが見当たりません。
文字数が70なので70未満の数値が必要…。そうなると70未満の数値を総当たりで試してみる事になります。その結果まともっぽい英文は得られましたが、微妙に変でした。

## BWT2
次は接尾辞配列を経由して構築するBWTの逆変換処理を施してみました。復元の為の70以下の数値を手あたり次第試す羽目になります。結論から言うとやはり失敗です。

## 真の解
私は真に驚くべき解法を導き出しましたが、それをここに書くには余白が狭過ぎます。
と、ここまでは茶番です。長い間お付き合い下さりありがとうございました。2007/12/13に奇妙な呟きが投稿されたというのもでっち上げです。
解読にはCodePenに投稿したおもちゃを使って下さい。呟きたい文字列を変換してから投稿して楽しむも良し。ちなみに絵文字には絶賛非対応中でございます。65000文字程度までは処理可能(手抜き)
<p class=codepen data-height="300" data-default-tab="result" data-slug-hash="ZEZPgGa" data-user="xezz" style="height:300px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;border:2px solid;margin:1em 0;padding:1em"> <span>See the Pen <a href="https://codepen.io/xezz/pen/ZEZPgGa">BWTS for tweet</a> by xezz (<a href="https://codepen.io/xezz">@xezz</a>) on <a href="https://codepen.io">CodePen</a>.</span></p><script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 参考文献
* [投稿元?](https://groups.google.com/g/comp.compression/c/SDTLJypCWvc/m/EpKGTnVtI6AJ)
* [高速版(github)](https://github.com/NealB/Bijective-BWT)
* [作者公式page](https://web.archive.org/web/20190613225314/http://bijective.dogma.net/compresa.htm)(作者は既に他界)
[Cloud Storage API(V2)] Javaで管理フォルダ(マネージドフォルダ)を生成・削除する

Cloud Storage API V2(Java)を使用して、
Cloud Storageの管理フォルダ(マネージドフォルダ)を生成・削除する方法
についてご紹介します。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Cloud Storage API(V2)] JavaでCloud Storageを使う](https://qiita.com/doran/items/2a5f7ef8070fd5b8c94d)
を参照ください。
:::

|No|||目次|
|---|---|---|---|
|1|||[管理フォルダを生成](#1-管理フォルダを生成)|
||1||[スコープ](#11-スコープ)|
||2||[実行](#12-実行)|
||3||[レスポンスの内容](#13-レスポンスの内容)|
|2|||[管理フォルダを削除](#2-管理フォルダを削除)|
||1||[スコープ](#21-スコープ)|
||2||[実行](#22-実行)|
||3||[レスポンスの内容](#23-レスポンスの内容)|

## 1. 管理フォルダを生成
指定したバケットに管理フォルダ(マネージドフォルダ)を生成します。

### 1.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
StorageScopes.CLOUD_PLATFORM
StorageScopes.DEVSTORAGE_FULL_CONTROL
StorageScopes.DEVSTORAGE_READ_WRITE
```
[⧉[Cloud Storage API(V2)] JavaでCloud Storageを使う(2.2 Storageインスタンスを取得)](https://qiita.com/doran/items/2a5f7ef8070fd5b8c94d#22-storageインスタンスを取得)
でスコープを指定してください。

### 1.2. 実行

```java
public static void main(String[] args) throws Exception{
    Storage storage = getStorage();
    Storage.ManagedFolders folder = storage.managedFolders();
    
    ManagedFolder content = new ManagedFolder();
    content.setName("管理フォルダの名前");
    Storage.ManagedFolders.Insert insert = folder.insert("バケットID",content);
    
    ManagedFolder res = insert.execute();
    System.out.println(res);
}
```
#### 1.2.1. HTTPリクエスト
POST:　https:\//storage.googleapis.com/storage/v1/b/{バケットID}/managedFolders
が実行されます。

#### 1.2.2. クエリパラメータ
クエリパラメータはありません。

#### 1.2.3. リクエストボディ
ManagedFolderのsetメソッドにより、リクエストボディを追加できます。

|メソッド|引数|説明|
|---|---|---|
|setName|String|【必須】管理フォルダの名前|

### 1.3. レスポンスの内容
#### ManagedFolder
|メソッド|戻り値|説明|
|---|---|---|
|getId|String|管理フォルダID|
|getName|String|管理フォルダ名|
|getKind|String|リソースの種類<br>固定文字列："storage#managedFolder"|
|getSelfLink|String|管理フォルダーURL|
|getBucket|String|管理フォルダーが含まれるバケットの名前|
|getCreateTime|DateTime|管理フォルダーが作成された時刻|
|getUpdateTime|DateTime|管理フォルダーが更新された時刻|
|getMetageneration|Long|メタ世代番号(metageneration)|

## 2. 管理フォルダを削除
指定した管理フォルダ(マネージドフォルダ)を削除します。

指定した空の管理フォルダを削除します。

このAPIで削除できるのは管理フォルダが空の場合のみです。
管理フォルダが空ではない場合は例外が発生します。

空ではない管理フォルダを削除する場合は、
Storage.ManagedFolders.Delete.set("allowNonEmpty", true);
を設定してexecute()すると正常にAPIは実行されます。
ただし、**管理フォルダ扱いではなくなるだけ**なので、オブジェクト自体は残ります。

### 2.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
StorageScopes.CLOUD_PLATFORM
StorageScopes.DEVSTORAGE_FULL_CONTROL
StorageScopes.DEVSTORAGE_READ_WRITE
```
[⧉[Cloud Storage API(V2)] JavaでCloud Storageを使う(2.2 Storageインスタンスを取得)](https://qiita.com/doran/items/2a5f7ef8070fd5b8c94d#22-storageインスタンスを取得)
でスコープを指定してください。

### 2.2. 実行

```java
public static void main(String[] args) throws Exception{
    Storage storage = getStorage();
    Storage.ManagedFolders folder = storage.managedFolders();
    
    Storage.ManagedFolders.Delete delete = folder.delete("バケットID","管理フォルダ名");
    
    delete.execute();
}
```
#### 2.2.1. HTTPリクエスト
DELETE:　https:\//storage.googleapis.com/storage/v1/b/{バケットID}/managedFolders/{管理フォルダ名}
が実行されます。

#### 2.2.2. クエリパラメータ
クエリパラメータはありません。。

### 2.3. レスポンスの内容
レスポンスはありません。
削除に失敗した場合は例外が発生します。

<br>
<br>
おしまい。。
Python Tools / Python Labs

# Python Tools / Python Lab

Python でツールを開発したり技術を研究したりしたものをアップしていきます。

## Python Tools

時々、公私で Python スクリプトのツールを作成しています。
うち、私的に作成したソースコードを公開していきます。

[Python ツール #1 ― 簡単なソースコードカウンター](https://qiita.com/tengbu-haoshou/items/b06a1ffd73332b0341f0)
[Python ツール #2 ― 簡単な Excel ファイル統計（ひな形）](https://qiita.com/tengbu-haoshou/items/6c190c49ced74a70f28f) 
[Python ツール #3 ― ファイルエンコーディングチェッカー ](https://qiita.com/tengbu-haoshou/items/fc8b849f6e300ea660d5)
[Python ツール #4 ― GUI でコマンド実行](https://qiita.com/tengbu-haoshou/items/44046982d555b9e6f999)
[Python ツール #5 ― PDF 操作（回転、結合）](https://qiita.com/tengbu-haoshou/items/6f5c2178a88e4c093409)

## Python Labs

時々、個人的に Python で技術研究しています。
そのソースコードを公開していきます。

[Python Lab #1 ― Flask with React/Vue](https://qiita.com/tengbu-haoshou/items/01255518c78b69f6136d)
[Python Lab #2 ― FastAPI with React](https://qiita.com/tengbu-haoshou/items/0399c2bc2b2667600d38)
[Python Lab #3 ― Selenium Web テスト自動化](https://qiita.com/tengbu-haoshou/items/2a30e1e8b9c9649e37c3)
[Python Lab #4 ― 顔認識 on GUI](https://qiita.com/tengbu-haoshou/items/bebb427b5b9ea80ace0a)
[Python Lab #5 ― 日本語解析 on GUI](https://qiita.com/tengbu-haoshou/items/b8afad165ca906dd8810)


## 説明で使用するソースコードのライセンス

MIT License

Copyright (c) 2024 Hirotoshi FUJIBE

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
PythonとTkinterを使用してExcelのデータ生成を助けるアプリケーションの作成

# PythonとTkinterを使用してExcelのデータ生成を助けるアプリケーションの作成

## はじめに

Excelでの作業を効率化するために、特定の形式のデータを迅速に生成し、簡単にコピペできるツールがあれば便利です。本記事では、Pythonのリスト内包表現を用いて、そのようなデータを生成し、クリップボードにコピーする小さなアプリケーションを作成する方法を紹介します。

## 使用技術

- Python 3
- Tkinter: GUIアプリケーションを作成するための標準ライブラリ
- `subprocess`: Windowsでクリップボードにアクセスするためのモジュール
- `pyperclip`: MacOS (およびその他のOS) でクリップボードにアクセスするためのモジュール
- `sys`: OSを識別するためのモジュール

## アプリケーションの設計

アプリケーションは以下の機能を持ちます：
- ユーザーがリスト内包表現を入力するテキストボックス
- 入力された表現を評価し、その結果を別のテキストボックスに表示するボタン
- 表示された結果をクリップボードにコピーする機能

## コードの解説

### GUIの設計

Tkinterを用いて、簡単なGUIを構築します。具体的なウィジェットは以下の通りです：
- `Text`: ユーザーが表現を入力するためのテキストボックス
- `Button`: 表現を評価し、結果を表示するためのボタン
- `Text`: 評価結果を表示するためのテキストボックス

### 評価機能

ユーザーが入力したリスト内包表現を`eval`関数を使用して評価します。結果はリストとして返され、これを一行ずつテキストボックスに表示します。

### クリップボードへのコピー

クリップボードへのコピーはOSに応じて異なる方法を使用します。Windowsでは`clip.exe`を、Macでは`pyperclip`を使用します。この部分の実装はOSを判断し、適切な方法を選択するようにしています。

## 実装コード

```python
import tkinter as tk
import subprocess
import sys

def evaluate_expression():
    expression = input_text_box.get("1.0", tk.END)
    try:
        # 文字列を評価してリストを生成
        result = eval(expression)
        output_text_box.delete("1.0", tk.END)
        # 結果を出力テキストボックスに表示
        for item in result:
            output_text_box.insert(tk.END, str(item) + "\n")
        # 結果をクリップボードにコピー
        copy_to_clipboard(output_text_box.get("1.0", tk.END))
    except Exception as e:
        print(e)

def copy_to_clipboard(text):
    if sys.platform == "win32":
        # Windowsの場合、clip.exeを使用
        p = subprocess.Popen(['clip.exe'], stdin=subprocess.PIPE, close_fds=True)
        p.communicate(input=text.encode('cp932', errors='ignore'))
    elif sys.platform == "darwin":  # MacOS
        try:
            import pyperclip
            pyperclip.copy

(text)
        except ImportError:
            print("pyperclip module not installed. Install it using pip.")

root = tk.Tk()
root.title("List Comprehension Evaluator")

input_text_box = tk.Text(root, height=5, width=50)
input_text_box.pack()

evaluate_btn = tk.Button(root, text="Eval", command=evaluate_expression)
evaluate_btn.pack()

output_text_box = tk.Text(root, height=10, width=50)
output_text_box.pack()

root.mainloop()
```

## まとめ

このアプリケーションを使用することで、Excelでのデータ入力作業を効率化できます。リスト内包表現を使って複雑なデータセットも簡単に生成し、Excelへのコピペをスムーズに行うことが可能です。ぜひ試してみてください。
2024/4/29主にITとかセキュリティの記事

2023年下半期ランサムウェア脅威動向：被害拡大とRaaSグループの活発化(4/26)
https://www.trendmicro.com/ja_jp/research/24/d/ransomware-by-the-numbers-2h-2023.html

自民党からのサイバーセキュリティ対策提言(4/26)
https://cybersecurity-jp.com/contents/librussc/526/

BitLockerの回復キーが求められる原因とは？回復キーの入手方法や解除方法を解説(4/26)
https://cybersecurity-jp.com/contents/data-security/3906/

「セキュリティの未来を担う：人材動向、収入の展望、そして必要なスキル」(4/26)
https://cybersecurity-jp.com/contents/librussc/506/

Facebook広告ツールに偽装したクレジットカードスキマーに注意(4/27)
https://news.mynavi.jp/techplus/article/20240427-2925894/

Google は Android TV のアカウント セキュリティの脆弱性をどのように修正したか(4/27)
https://kenmin-souko.jp/google-%E3%81%AF-android-tv-%E3%81%AE%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%81%AE%E8%84%86%E5%BC%B1%E6%80%A7%E3%82%92%E3%81%A9%E3%81%AE/

スイスで広がるネット投票　本格導入には採算性が課題に(4/27)
https://www.swissinfo.ch/jpn/%e5%9c%a8%e5%a4%96%e3%82%b9%e3%82%a4%e3%82%b9%e4%ba%ba/%e3%83%8d%e3%83%83%e3%83%88%e6%8a%95%e7%a5%a8/76330875?utm_source=multiple&utm_campaign=swi-rss&utm_medium=rss&utm_content=o

ネイバー・LINEに圧力かける日本、928万件の個人情報を流出させたNTTには軽い処罰(4/27)
https://www.chosunonline.com/site/data/html_dir/2024/04/27/2024042780025.html

LINEヤフーが報告書 個人情報保護委に　漏洩巡り防止策(4/27)
https://www.nikkei.com/article/DGKKZO80328860W4A420C2TB0000/

「忘れられる権利」は忘れられたのか？　個人情報の削除依頼が減少(4/27)
https://news.yahoo.co.jp/articles/b0019e1d379e11af3ba45596a065e2b2c3f97d08?source=rss

中国、統計改ざんの処罰拡大へ　法改正に着手(4/27)
https://www.toonippo.co.jp/articles/-/1768210
https://www.chunichi.co.jp/article/891075?rct=economics

社内失業者400万人という話を読んで(4/27)
https://blogs.itmedia.co.jp/satou55_makoto/2024/04/400.html?ref=rss

中国SNSを見てたら自分の家の室内映像が出てきてビックリ！その真相は…―台湾メディア(4/27)
https://news.livedoor.com/article/detail/26306761/

「パパ、大丈夫？」被害額“過去最多”　クレジットカードを不正利用された報道カメラマンの実体験と教訓(4/27)
https://nordot.app/1156765257910305691

【寄稿】中国「情報支援部隊」新設に見る戦略の大転換　「ペンは剣より強し」は真理か苦肉の策か(4/27)
https://www.epochtimes.jp/2024/04/220773.html
Javaで「Javaの予約語」の動作を確認してみた

# 概要

Javaで「Javaの予約語」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/const/index7.html

# 実装

以下のファイルを作成しました。
```JSample7_1.java
class JSample7_1{
  public static void main(String[] args){
    int switch;
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample7_1.java 
JSample7_1.java:3: エラー: 文ではありません
    int switch;
    ^
JSample7_1.java:3: エラー: ';'がありません
    int switch;
       ^
JSample7_1.java:3: エラー: '('がありません
    int switch;
              ^
JSample7_1.java:5: エラー: 構文解析中にファイルの終わりに移りました
}
 ^
エラー4個
```

# まとめ

何かの役に立てばと。
POSTメソッドがGETメソッドになるエラーの解消法

Railsのアプリケーションにおいて、HTTPメソッドが期待どおりに動作しないという問題に直面しました。ここでは、問題の原因とその解決策について説明します。

## 問題の概要

- お気に入りに追加するためのボタンがクリックされても、お気に入り登録されませんでした。
- ボタンは`button_to`ヘルパーを使用しており、`POST`リクエストを送信することが期待されていました。

## 原因

原因は、`button_to`が`form_with`の内部に配置されていたため、ネストされたフォームが作成されていました。これは、HTMLのフォームの中に別のフォームをネストすることはできないというルールに反しています。結果として、`button_to`による`POST`リクエストが発生しなくなっていました。

## 解決策

解決策として、`button_to`を`link_to`に置き換え、`data-turbo-method`属性を使用して`POST`リクエストを送信するように変更しました。

```変更前.erb
<%= button_to 'お気に入りに追加', favorite_companies_path(company_id: viewing_company.id), data: { turbo_method: :post }, class: 'btn btn-info'  %>
```

```変更後.erb
<%= link_to 'お気に入りに追加', favorite_companies_path(company_id: viewing_company.id), data: { turbo_method: :post }, class: 'btn btn-info'  %>
```

## 変更後のコード

以下のコードは、変更を加えた部分を示しています。`link_to`ヘルパーを使用し、適切に`POST`リクエストが送信されるようにしました。

```erb
<% if current_customer %>
  <% if current_customer.companies.include?(viewing_company) %>
    <!-- お気に入り解除のボタン -->
  <% else %>
    <div class="form-group d-flex align-items-center me-2">
      <%= link_to 'お気に入りに追加', favorite_companies_path(company_id: viewing_company.id), data: { turbo_method: :post }, class: 'btn btn-info' %>
    </div>
  <% end %>
<% end %>
```

`data-turbo-method`属性を使って、Turbo DriveがAjaxリクエストとしてこのリンクを扱うように指定しました。これにより、ユーザーが「お気に入りに追加」ボタンをクリックすると、背後で`POST`リクエストが送信され、お気に入りとして登録されます。

## 結果

この変更により、お気に入り機能は期待通りに動作し、ユーザーが企業をお気に入りに追加できるようになりました。

---

この記事がお気に入り機能の実装で遭遇する可能性のある問題とその解決策について理解を深めるのに役立つことを願っています。
```
Cookieの破棄されるタイミングについて

## はじめに
備忘録です

## Cookieの有効期限の違い
Cookieを保存する際は有効期限を設定できるのですが、設定はオプションです。
有効期限をつけた場合とつけない場合の違いを見てみます。

### Cookieに有効期限をつけない場合
Cookieは検証ツール → Application → Cookiesで確認可能です。
有効期限を設定しない場合、Expiresには`Session`と記載されます。
有効期限を設定しないCookieは特別に`Session Cookie`と呼ばれるそうです。
有効期限はブラウザを閉じるまでです。
注意点はタブを閉じても削除はされない点です。 また、ブラウザをリロードしても削除されません。
![スクリーンショット 2024-04-29 1.01.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1390680/b459d247-e64a-9cda-5ebb-e5ece00e9394.png)


### 有効期限を設定した場合
有効期限を設定した場合、Expiresには有効期限が表示されます。
有効期限内はブラウザを閉じても、リロードしてもCookieは保持され続けます。
有効期限が切れた場合、ブラウザを終了したら削除されるのはもちろん、画面のリロードでも破棄されます。

![スクリーンショット 2024-04-29 1.14.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1390680/dbc0b251-4bb1-fd31-9482-ab0486a79a8c.png)


## おわりに
今回の検証を行った動機はRailsのsessionやcookiesといったメソッドを利用している際に、cookieの保存方法に何か違いはあるのだろうか。という疑問が生じたからです。

Railsのsessionメソッドでcookieに保存されるsession_idは、なぜブラウザ閉じたら勝手に消えるのだろう。と考えていたのですが、単に有効期限を設定せずにcookieに対して値を保存すると、デフォルトでそうなるブラウザ側の仕様だったのです。このことから、cookieメソッドで保存した場合でも有効期限を設定しない場合同じ挙動になることを理解できました。
​PowerShellでテキスト

```powershell
​​#Excelファイルのパス
​​$excelFilePath = "C:\Path\To\Your\File.xlsx"
​​
​​#Excelファイルを開く
​​$excel = New-Object -ComObject Excel.Application
​​$excel.Visible = True
​​$excel.ScreenUpdating = False
​​$workbook = $excel.Workbooks.Open($excelFilePath)
​​$textFileBaseName = Split-Path -Path $excelFilePath -Leaf
$textFilePath = ​​$textFileBaseName + ".txt"
​​
​​#各シートをテキストファイルにコピー
​​foreach ($sheet in $workbook.Sheets) {
​​    $sheetName = $sheet.Name
​​    $usedRangeValue = $sheet.UsedRange.Value
​​    $text = ""
​​    foreach ($row in $usedRangeValue) {
​​    $text += ($row -join "`t") + "`n"
​​   }
    Add-Content -Path $textFilePath -Value $text -Append
​​}
​​
​​#Excelファイルを閉じる
​​$workbook.Close()
​​$excel.Quit()
​​[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet)
​​
​​
Next.jsとLaravelを使ったSanctum認証とSSRフェッチ時に必要な対応

## はじめに
本記事では、Next.jsとLaravelを使用したアプリケーション開発中に遭遇する可能性のある認証関連の問題に焦点を当てています。具体的には、サーバーサイドレンダリング(SSR)時に`Laravel Sanctum`を用いた認証を行う際の一般的なエラーと、その解決策について解説します。

## エラー
- エラー内容はSSR内にてサーバーサイドフェッチ時apiを実行すると`401 Unauthenticated`が返ってきてしまうものです。

## 原因
この問題の主な原因は、SSR中にAPIリクエストを行う際、適切な`Referer`ヘッダーや`Origin`ヘッダーが設定されていないことにあります。Laravel Sanctumではこれらのヘッダーを利用してリクエストがアプリケーションのフロントエンドから送信されたものであることを検証するらしいです、、、。

## 解決策
1. **APIリクエストのヘッダーに`Referer`と`Origin`を含める**: Next.jsからのすべてのAPIリクエストに、正しい`Referer`ヘッダーと`Origin`ヘッダーを明示的に設定します。これにより、Laravelがリクエストの正当性を認識し、CSRFトークンエラーを回避できます。

   ```javascript:(SSR実行ファイル)
   fetch("https://yourdomain.com/api/endpoint", {
       method: "GET", // または POST, PUT など
       headers: {
           'Referer': 'https://yourdomain.com',
           'Origin': 'https://yourdomain.com'
       },
       credentials: 'include' // クッキーを送信するために必要
   });
   ```

2. **セッションの設定を確認する**: LaravelとNext.jsの間でセッションが正しく共有されているかを確認します。`SANCTUM_STATEFUL_DOMAINS` の設定を適切に行うことで、セッションの維持が可能です。

## 結果
上記の変更を加えた後、SSRでの認証プロセスが正常に機能し、`CSRF token mismatch`のような エラーが解消されました。

## 終わりに
この問題はNext.jsとLaravelのSanctumを組み合わせて使用する場合に必要な対応であり、適切なヘッダーの設定が必要です。
公式にはそこまでの情報は書いてないので、同じエラーが出た人の助けになれば幸いです！！

## 参考
https://zenn.dev/nicopin/articles/2cf7d90edc8b07

https://github.com/nuxt/nuxt/issues/12346
ハードリンクは超便利！



シンボリックリンクに対して、
使い道がないといわれがちなハードリンク

それが思いのほか便利だったので、
（超というと大げさだけど）
その使い道を紹介してみる

# gitのあるディレクトリ内にハードリンクを作成することで、git管理する

- gitがないディレクトリのファイルを、git管理したいとき
- プロジェクトのリポジトリをローカルにクローンしているしていて、プロジェクトのcommit履歴を汚したくないが、個人的に細かな変更履歴を残しておきたいとき

# シンボリックリンクとの比較
## ハードリンクのメリット

- ファイルを移動させたときや、親ディレクトリの名前を変更してもリンクが切れない
- リンク元のファイルを削除しても、リンク先のファイルをが削除されない（そもそもどちらがリンク元かリンク先なのかの区別はない）

## ハードリンクのデメリット

- ファイルシステムをまたいだハードリンクは作れない
- ディレクトリのハードリンクは作れない

# ハードリンクの作り方[^1]

## Linuxの場合

```bash
ln [リンク元ファイルパス] [リンク先ディレクトリパス]
```

[^1]:細かなオプションとかはこれを参照
[ln コマンド - IBM Documentation](https://www.ibm.com/docs/ja/aix/7.2?topic=l-ln-command)

## windowsの場合

### powershellでは

```powershell
New-Item -ItemType HardLink -Path [リンク元ファイルパス] -Target [リンク先ファイルパス]
```

### コマンドプロンプトでは

```bat
mklink /h [リンク元ファイルパス] [リンク先ファイルパス]
```

または

```bat
fsutil hardlink create [リンク元ファイルパス] [リンク先ファイルパス]
```

### エクスプローラーで使いたい場合

リンク作成シェル拡張というツールを使えばできる。

[「リンク作成シェル拡張」異なるパスで同じファイルやフォルダーを表すためのツール - 窓の杜](https://forest.watch.impress.co.jp/library/software/lik_shellex/)

# 参考

[シンボリックリンクとハードリンクの違いって？ #Linux - Qiita](https://qiita.com/nyancook/items/05a6d2a96b74b88d9761)

[Windowsのハードリンクとジャンクションとシンボリックリンクについて #PowerShell - Qiita](https://qiita.com/SAITO_Keita/items/eae21799fd3d136cb813)

[【Windows File System】Windowsでハードリンクやシンボリックリンクを作る | dotいがの快適インターネット](https://dotiga.jp/windows/win-os/2022-create-hard-links-and-symbolic-links-in-windows)
【AWS】Lambda⇒DynamoDBへデータを書き込んでみるハンズオン

# はじめに
Lambda⇒DynamoDBへ書き込みについて学習したのでその振り返り記事となります。
本記事はLambda⇒DynamoDBへ書き込み処理部分を実装できるようになることを目的としたハンズオン形式の記事になります。


# ゴール
lambdaからdynamoDBにデータの書き込みができるようになる。

# 環境
- Lambda(Node.js 16.x)
- DynamoDB


# DynamoDB側の準備
DynamoDBからリソースを作成していきます。

### ◆テーブルの作成

DynamoDB > テーブル > テーブルの作成 からテーブル名とパーティションキーを入力します。
入力出来たらページ下部の「テーブルの作成」ボタンをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/2e8cb22d-37db-5f4d-5d2e-33d0797de2b7.png)


# Lambda側の準備
Lambdaを準備していきます。

### ◆関数の作成

Lambda > 関数の作成から関数を作っていきます。
「一から作成」を選択し、任意の関数名、ランタイムを設定し実行ロールはいったん「基本的な Lambda アクセス権限で新しいロールを作成」にチェックしておきます。
入力出来たらページ下部の「関数の作成」ボタンをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/0ab091d9-9ec0-9e8c-2b39-17a0a35e237f.png)


### ◆実行ロールの追加
デフォルトのロールでは必要な権限が足りてないのでロールを追加します。
Lambda > 関数 > 関数名 > 設定タブからアクセス権限の設定をクリック。
表示されるロール名をクリックするとIAMのページに遷移するので、許可を追加 > インラインポリシーを作成を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/aa7388a1-a4f7-b37a-5a35-6f773a5ba8b4.png)

- アクション 許可：検索バーに「PutItem」を入力し書き込み権限を選択
- リソース：特定にチェックを入れ、DynamoDBの「arnを追加」をクリック。
表示されたポップアップの「リソースARN」の欄にDynamoDBのARNをコピペします。コピペが完了したら「ARNを追加」を選択します。


＜ポップアップ＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/25b51399-cec6-7879-031e-6ac3c4ba491c.png)


＜DynamoDBのARN＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/8af2d6ef-4b1c-d974-87d7-2767c8d9998f.png)



上記を完了し、再度先ほど開いていたIAM > ロール > 対象のロール名のページに戻ります。
「許可ポリシー」の欄を確認すると、作成したものが追加されている事を確認できます。



### ◆処理内容の作成

Lambda > 関数 から作成した関数名を選択しコードを設定していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/0959043e-ec2f-d02c-f071-77a3195d64db.png)


index.jsに対して以下のようにコードを記述します。
処理の詳細はコメントアウトの通りです。

```index.js
const AWS = require('aws-sdk');

// DynamoDB クライアントを作成
const dynamoDB = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event) => {
  try {
    // DynamoDB に挿入するデータ
    const params = {
      TableName: 'dynamoDBのテーブル名',
      Item: {
        dynamoid: 'testhogehgoe',
      }
    };

    // データを挿入
    await dynamoDB.put(params).promise();

    return {
      // 書き込み成功
      statusCode: 200,
      body: JSON.stringify('Data inserted successfully')
    };
  } catch (error) {
    return {
      // 書き込み失敗
      statusCode: 500,
      body: JSON.stringify('Error inserting data: ' + error.message)
    };
  }
};
```

### ◆実行 & 結果

ここまで出来たらコードタブの「Deploy」ボタンをクリックし変更内容を更新します。
合わせて「Test」からイベントを作成し再度「Test」ボタンをクリックし処理を実行してみます。

**結果**：200番が返ってきておりdynamodbへの書き込みが成功している事を確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/07bae665-b057-250e-3ed7-0ce7a8df6878.png)

DynamoDB > 項目を探索 > テーブル名 から書き込まれた内容も確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/0e357e81-f2de-3c1a-fef9-fab52a118bf2.png)
Module 'Nuke' has no member named 'loadImage' とNo such module 'NukeExtensions' になる

# はじめに

https://pixiv.github.io/ios-tutorial/tutorials/tutorial/practice4

pixivのTutorialをやっていてNukeでつまずいたのでメモ

# Nuke.loadImageが使えない
NukeのバージョンによってNuke.loadImageが使えなくなっているようでしたので解決方法を探して
```
import NukeExtensions
```
をインポートしてようとしましたが､No such module 'NukeExtensions' とエラーになってしまう｡

# 解決方法
### 私の場合はAdd to TargetがNoneになっていたのが原因でしたのでNukeをSPMで入れなおしました｡
以下画面に行きます｡
![スクリーンショット 2024-04-28 22.30.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/2e95bd28-f990-6648-3fe6-89247489567b.png)

Nukeを選択した-(マイナス)ボタンで1度アンイストールします｡
![スクリーンショット 2024-04-28 22.30.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/18a4fdfc-dbcc-88d0-50f3-57d0cfc42c4f.png)

+(プラス)ボタンで再度追加
![スクリーンショット 2024-04-28 22.31.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/482b1ca0-6fe1-8010-2f3b-64990840f3aa.png)

このとき Add to TargetがNoneになっていたのが原因でした｡
![スクリーンショット 2024-04-28 22.31.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/c1864f4c-3173-1d32-4460-880f5bfde107.png)

Add to Targetを追加してAdd Packageします｡
![スクリーンショット 2024-04-28 22.32.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/a793e44c-f452-b706-a95f-6d0796f64eb5.png)

これで
```
import NukeExtensions
```
してもNo such module 'NukeExtensions' エラーは出ません｡

以下の記述でloadImageが使用できます｡
```swift
loadImage(with: illst.imageURL, into: imageView)
```
# 参考
https://github.com/kean/Nuke

https://qiita.com/pe-pe-engineer/items/c05ca04c6d75968f6467
思考のスピードで飛び回れるNvimプラグインhop.nvimの紹介

# はじめに
今回はneovim完全対応でeasymotionのように，画面を縦横無尽に飛び回れるプラグインを見つけたので紹介します．これがあれば開発効率上がること間違いなし！

# 使い方（単語全表示の場合)

### 1
現在カーソルが25行にあり画面一番下71行の後ろにあるmethodsという単語に飛びたいとします
![スクリーンショット 2024-04-28 23.42.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777414/ddcf943f-e8d8-8cb2-f369-ec8b2dc0e852.png)
### 2
コマンドを呼び出すと，全ての単語にバインドが割り振られるので，今回はjjと入力します
![スクリーンショット 2024-04-28 23.42.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777414/2c38763f-deb4-ba4c-5635-7cf66e2922dd.png)
### 3
はい．もう移動できました！
![スクリーンショット 2024-04-28 23.43.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777414/5573e05c-d907-a83d-6893-62cdd724524d.png)


# hop.nvim
https://github.com/hadronized/hop.nvim

自分はこの手のプラグインはeasymotionしか知らなかったので，ずっと使っていたのですがバッファが書き換わるのでLSPがいちいち反応してうるさいなと思っていました．
hop.nvimは，この問題を解決するためにUIプラグインは既存のバッファに変更を加えるべきではないというコンセプトをもとに最新のneovimに実装したプラグインのようです．最高だ．

## インストール方法
僕と同じ，lazy.nvimの場合は

```lua:hop.lua
return {
  "phaazon/hop.nvim",
  branch = "v2",
  config = function()
    require("hop").setup {
      multi_windows = true,
    }
  end,
  keys = {
    {mode = "", "<leader>s", "<cmd>HopChar<CR>", desc = "説明"},
  }
}
```
でインストールと設定ができます．
multi_windowsはウィンドウをいくつか広げているときに，全てのウィンドウが検索対象にすることができる設定です．  他にも色々設定項目ありましたが，基本的にはデフォルトから変えることはあまりなさそうでした．

## 機能紹介
個人的に特に便利だと思うコマンドを３つ紹介します．

* ```:HopWord```
バッファ内の全ての単語がある場所に移動できます

* ```:HopChar2```
2文字を指定して，検索をかけて移動することができます

* ```:HopPattern```
vim標準の/と同じように検索をかけることができます．標準では１つずつしか移動できないのに対して，こっちはヒットした対象から任意の箇所に一瞬で飛べちゃう．

この辺りをキーバインディングに設定しておけばかなり便利だと思います．