OmniAICreator/Qiita-1.07M huggingface dataset:
うぇと

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# ファイルの読み込み
file_path = 'path_to_your_local_file/合成用資料_1.xlsx'  # ローカルファイルのパスに置き換えてください
data = pd.read_excel(file_path)

# 日付をdatetime型に変換
data['TDATE'] = pd.to_datetime(data['TDATE'], format='%Y%m%d')

# 1年ごとの期間設定
years = data['TDATE'].dt.year.unique()

# ファクターポートフォリオの構築と評価
factor_names = ['EST_SENTIMENT', 'EST_LIQUIDITY', 'INCM_NORM']
results = {year: {factor: [] for factor in factor_names} for year in years}

for year in years:
    year_data = data[data['TDATE'].dt.year == year]
    for factor in factor_names:
        factor_portfolio = year_data.sort_values(by=factor, ascending=False).iloc[:int(len(year_data) * 0.1)]
        cumulative_return = (factor_portfolio['ROR1MF'] / 100 + 1).prod() - 1
        average_return = factor_portfolio['ROR1MF'].mean()
        risk = factor_portfolio['ROR1MF'].std()
        sharpe_ratio = average_return / risk if risk != 0 else np.nan

        results[year][factor] = {
            'Cumulative Return': cumulative_return,
            'Average Return': average_return,
            'Risk': risk,
            'Sharpe Ratio': sharpe_ratio
        }

# ウェイトの計算
weights = {}
for year in years:
    weights[year] = {}
    total_sharpe = sum(results[year][factor]['Sharpe Ratio'] for factor in factor_names if results[year][factor]['Sharpe Ratio'] > 0)
    for factor in factor_names:
        sharpe_ratio = results[year][factor]['Sharpe Ratio']
        weights[year][factor] = sharpe_ratio / total_sharpe if total_sharpe > 0 else 1 / len(factor_names)

# ウェイトを適用した戦略合成の計算
strategy_results = []
for year in years:
    year_data = data[data['TDATE'].dt.year == year]
    year_strategy_return = np.zeros(len(year_data))
    for factor in factor_names:
        weight = weights[year][factor]
        normalized_factor = (year_data[factor] - year_data[factor].mean()) / year_data[factor].std()
        year_strategy_return += weight * normalized_factor
    strategy_results.append({
        'Year': year,
        'Strategy Return': year_strategy_return.mean()
    })

# 結果のデータフレーム化
strategy_results_df = pd.DataFrame(strategy_results)

# プロットの準備
years = strategy_results_df['Year']
strategy_returns = strategy_results_df['Strategy Return']

# 比較のための正規化した単純合成
simple_composite = (data['EST_SENTIMENT'] + data['EST_LIQUIDITY'] + data['INCM_NORM']) / 3
simple_composite_return = []
for year in years:
    year_data = data[data['TDATE'].dt.year == year]
    simple_composite_return.append(simple_composite[year_data.index].mean())

# プロット
plt.figure(figsize=(12, 8))
plt.plot(years, simple_composite_return, label='Simple Composite', marker='o')
plt.plot(years, strategy_returns, label='Strategy Composite', marker='x')
plt.xlabel('Year')
plt.ylabel('Average Return')
plt.title('Simple Composite vs Strategy Composite Returns')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
ｍｍ

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# ファイルの読み込み
file_path = 'path_to_your_local_file/合成用資料_1.xlsx'  # ローカルファイルのパスに置き換えてください
data = pd.read_excel(file_path)

# 期間定義
periods = {
    '2014-2015': ('2014-04-30', '2015-12-31'),
    '2016-2019': ('2016-01-01', '2019-12-31'),
    '2020-2021': ('2020-01-01', '2021-12-31'),
    '2022-2024': ('2022-01-01', '2024-04-30')
}

# ファクターポートフォリオの構築と評価
factor_names = ['BPR', 'EST_SENTIMENT', 'EST_LIQUIDITY', 'INCM_NORM', 'ROA', 'Sales Growth', 'Price Momentum']
results = {factor: [] for factor in factor_names}

for period, (start, end) in periods.items():
    period_data = data[(data['TDATE'] >= pd.to_datetime(start)) & (data['TDATE'] <= pd.to_datetime(end))]
    
    for factor in factor_names:
        factor_portfolio = period_data.sort_values(by=factor, ascending=False).iloc[:int(len(period_data) * 0.1)]
        cumulative_return = (factor_portfolio['ROR1MF'] / 100 + 1).prod() - 1
        average_return = factor_portfolio['ROR1MF'].mean()
        risk = factor_portfolio['ROR1MF'].std()
        sharpe_ratio = average_return / risk if risk != 0 else np.nan
        
        results[factor].append({
            'Period': period,
            'Cumulative Return': cumulative_return,
            'Average Return': average_return,
            'Risk': risk,
            'Sharpe Ratio': sharpe_ratio
        })

# 結果の集計と視覚化
results_df = pd.DataFrame([(factor, period, res['Cumulative Return'], res['Average Return'], res['Risk'], res['Sharpe Ratio'])
                           for factor, values in results.items()
                           for period, res in zip(periods.keys(), values)],
                          columns=['Factor', 'Period', 'Cumulative Return', 'Average Return', 'Risk', 'Sharpe Ratio'])

# 各指標の棒グラフ作成
for metric in ['Cumulative Return', 'Average Return', 'Risk', 'Sharpe Ratio']:
    fig, ax = plt.subplots(figsize=(12, 8))
    for factor in factor_names:
        subset = results_df[results_df['Factor'] == factor]
        ax.bar(subset['Period'], subset[metric], label=factor)
    
    ax.set_title(f'{metric} by Factor and Period')
    ax.set_xlabel('Period')
    ax.set_ylabel(metric)
    ax.legend(title='Factor')
    plt.xticks(rotation=45)
    plt.tight_layout()
    plt.show()
robloxでassistant その90

# 概要
robloxでassistantやってみた。
練習問題やってみた。

# 練習問題
Raycastを使え。

# 手順
- ServerScriptServiceに、scriptを追加。
- スクリプトを書く。
```

local part = Instance.new("Part", workspace)
part.Anchored = true
part.Position = Vector3.new(0, 10, 0)
local rayOrigin = Vector3.new(0, 0, 0)
local rayDirection = Vector3.new(0, 30, 0)
local raycastResult = workspace:Raycast(rayOrigin, rayDirection)
if raycastResult then
	print("hit")
end
local distance = (rayOrigin - rayDirection).Magnitude
local p = Instance.new("Part", workspace)
p.Anchored = true
p.CanCollide = false
p.Size = Vector3.new(0.1, distance, 0.1)
p.CFrame = CFrame.new(rayOrigin)
p.BrickColor = BrickColor.Red()


```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c317ff9e-1ad6-d2a6-59a7-7a019be49a3e.png)


以上。
SpringでWebFlux FluxとThymeleafを使う件

## 何についてか
https://qiita.com/pocketgroovy/items/dd8c2d37aca4b2dcfb9b

の続編でFluxについても書いておきます。

## 結論
Monoと同じくmapを使ってもOK。やはりreturn形式は"Mono&lt;String>"であること。
```
    @GetMapping("/hello")
    public Mono<String> hello(Model model) {
        Flux<DataDTO> dataMono = dataService.getData();
        return dataMono.collectList().map(data -> 
            model.addAttribute("data", data)).then(Mono.just("index"));
    }
```
* .collectList()はMono<list<DataDTO>>を返してきます。つけ忘れると最後のdataしか処理されなかったです。さらに注意したいのは全てのリストの取得が終わるまで続けるので、out of memoryで落ちるまで終わらないらしいです。
* Monoの時と違ってdataの取得に時間がかかり非同期なのでthymeleaf側でnullとして判断されてしまう可能性が高いので、必ず処理が終わってからThymeleafに渡すために、thenをつかっています。

## 方法２
```
    @GetMapping("/hello")
    public Mono<String> hello(Model model) {
        Flux<DataDTO> dataMono = dataService.getData();
        return dataMono.collectList().doOnNext(data -> 
            model.addAttribute("data", data)).then(Mono.just("index"));
    }
    
```
確実にdataが利用されている状態で処理したいのでdoOnNextを使った方がよさそうです。

## 他に試したこと
```
    @GetMapping("/hello")
    public String hello(Model model) {
        Flux<DataDTO> dataMono = dataService.getData();
        dataMono.collectList().subscribe(data -> 
            model.addAttribute("data", data));
        return "index";
    }
    
```
・やはり処理が非同期でおこなわれているためdataはnullでした


## まとめ
MonoもFluxもその特徴である非同期処理のため、そのデータが処理する時に必ず存在しているかどうかを確認することが重要なポイントの一つのようです。
Fluxで受けたdataも最終的にはMonoにすることでThymeleafと会話することができました。

## 参考資料
Flux vs Mono
https://www.geeksforgeeks.org/difference-between-mono-and-flux-in-spring-webflux/
Class Flux<T>
https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html#map-java.util.function.Function-
AWSの公式ドキュメントが修正されるに至った経緯

# ことのはじまり
@kohki_takatama さんの記事 [XMLのイメージを掴む
](https://qiita.com/kohki_takatama/items/d9a255fa12b6b2c54430) が投稿される

https://qiita.com/kohki_takatama/items/d9a255fa12b6b2c54430

## HTML / XML のリリースされた年 が 1998 / 1993 となっておりおかしいことに気が付いてコメントする

> > | | HTML | XML |
> > | --- | --- | --- |
> > | リリースされた年 | 1998 年 | 1993 年 |
> 
> 逆では？
> 
> > June 1993
> 
> https://www.w3.org/MarkUp/draft-ietf-iiir-html-01.txt
> 
> > 1993年にはIETFからHTML仕様書バージョン1.0が公開され、SGMLからの拡張として文法定義のDTDを持つようになった。
> 
> https://ja.wikipedia.org/wiki/HyperText_Markup_Language
> 
> > XML の仕様は、World Wide Web Consortium (W3C) により策定・勧告されている。1998年2月に XML 1.0 が勧告された。
> 
> https://ja.wikipedia.org/wiki/Extensible_Markup_Language
> 

https://qiita.com/kohki_takatama/items/d9a255fa12b6b2c54430#comment-cd715234e23cfbe85d2b

## どうも元のドキュメントがおかしいことに気が付く

※ただし、私はAWSアカウントを持っていないので別の方法で報告する必要がある為 x.com でまとめることにする

https://aws.amazon.com/jp/compare/the-difference-between-html-and-xml/

https://x.com/juners/status/1790931573749194979

# 日本語AWSの x.com アカウントに報告する

https://x.com/juners/status/1790942190367301842

## どうも 英語版のドキュメントからそうなことに気が付く

https://aws.amazon.com/compare/the-difference-between-html-and-xml/?nc1=h_ls

# x.com の [@awssupport](https://x.com/AWSSupport) に AWS のドキュメントがおかしいことを報告する

https://x.com/juners/status/1790943500210704646

https://x.com/AWSSupport/status/1790948532339212645

とりあえず報告してもらえたみたい

# AWS のドキュメントが修正され、その報告を受ける

https://x.com/AWSSupport/status/1795906063562158318

感謝の気持ちを忘れずに。 `thanks you!` を返す。

以上。
React Projectでスムーズなスクロールを実装する際の備忘録

## 執筆の動機
Reactでポートフォリオを作成していた際に、スムーズスクロールを実装しようと考え様々なサイトを当たったが、どのサイトもReactベースではなく、何も考えずコピペ実装したかった私のニーズに合うページが見つからなかった。
## 前提
以降はこのディレクトリ構成を前提として解説する。
```
src
├── App.js
├── App.test.js
├── SmoothScroll.js
├── index.css
├── index.js
├── reportWebVitals.js
├── setupTests.js
└── styles
    ├── App.css
    └── Navbar.css
```

## locomotive-scrollとは
[Perry Wang氏のポートフォリオ](https://www.perryw.ca/info)を眺めていた際に、スクロールの動きの美しさに惚れたのがきっかけ（一度は見た方がいい美しいポートフォリオです。他にも様々参考になる点がありました。）でlocomotive-scrollに出会いました。
簡単にスムーズスクロールが実装できるので嬉しいというメリットがあります。

## 実装
### npm install
プロジェクトのディレクトリに移動したら
```
npm i locomotive-scroll
```
を実行し、インストール。

### React Componentの作成
```/src/components/SmoothScroll.js
import React, { useEffect, useRef } from 'react';
import LocomotiveScroll from 'locomotive-scroll';

const SmoothScroll = ({ children }) => {
  const scrollRef = useRef(null);

  useEffect(() => {
    const scroll = new LocomotiveScroll({
      el: scrollRef.current,
      smooth: true,
    });

    return () => {
      if (scroll) scroll.destroy();
    };
  }, []);

  return <div data-scroll-container ref={scrollRef}>{children}</div>;
};

export default SmoothScroll;

```

### Componentの配置
以下のように、適用されて欲しい範囲をSmoothScrollで囲ってあげればOK。
```/src/App.jsx
import React from 'react';
import SmoothScroll from './components/SmoothScroll';
import './App.css';

const App = () => {
  return (
    <SmoothScroll>
      <main>
        {/* ここにプロジェクトの大部分をブチ込む */}
      </main>
    </SmoothScroll>
  );
};

export default App;
```

## まとめ
以上ReactでLocomotive scrollを実装する方法でした。思ったより簡単にできるのでみなさんもぜひ実装してみてください！ヌルヌルスクロールできてQOL上がります！
どぁ

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

# データの読み込み（仮のデータフレーム名を df とします）
df = pd.read_csv('path_to_your_data.csv')

# TDATE を datetime オブジェクトに変換
df['TDATE'] = pd.to_datetime(df['TDATE'], format='%Y%m')

# 相関行列の計算
correlation_matrix = df[['BPR', 'EST_SENTIMENT', 'EST_LIQUIDITY', 'INCM_NORM']].corr()

# ヒートマップの作成
plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', fmt=".2f")
plt.title('Correlation Matrix of Factors')
plt.show()
Copilotさんのディープラーニングとネット検索を組み合わせた回答が素晴らしいという話



# はじめに：Qiitaのアクセス解析



Qiitaにアナリティクスを登録してあるので、たまに確認するのですがcopilot.microsoft.comからのアクセスがあることに気づきました。



自分の記事が学習されているようなのでCopilotの動作を確認してみました。ちょっと面白い動きをしていたのでまとめておきます。





# Copilotの動作を確認してみる



Copilotの回答の参照先として私のQiita記事のリンクが表示されてクリックしたと思われるので確認してみます。



View数、いいね数が多い記事であればCopilotの推奨回答としてリンクされると推測して、正解ありきの質問をCopliotさんに聞いてみました。








> 質問：PowerShellでタスクトレイに常駐することができますか


想定回答リンク：[私PowerShellだけど、君のタスクトレイで暮らしたい](https://qiita.com/magiclib/items/cc2de9169c781642e52d)

![1000005097.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/219d9694-8f76-684c-82ef-343da1763f1c.png)





詳細情報 の１番目に私のQiita記事が表示されています。ここのリンクをクリックした人がいるようです。

回答の内容は私の記事の内容を踏襲していますが、ソースコードの便利機能や、冗長な部分がカットされた最小構成になっていてCopliotの要約機能はすごいですね。





# Copilitは最新の情報に対応できている？



何パターンか確認したのですが、ちゃんとQiita記事が学習されているようでした。



学習が完了している記事でないと回答できないはずと想定して、この調査の前日にアップした記事について、回答できない失敗パターンとして質問してみました。


> 質問：PowerShellでスクリーンショットを取得したい

想定回答リンク：[私PowerShellだけどスクリーンショットを撮影したい](https://qiita.com/magiclib/items/91f7d32cbd766b39b293)



![1000005098.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/b17fbd6d-d593-5d6e-0cb5-0fa09cc3b3f0.png)


この質問も 詳細情報 の１番目に私のQiita記事が表示されていました。

Copilotは昨日アップした記事について回答できるの？すごいですね。



ネット上に該当情報が無いことを確認してから記事を書いているので、この質問に回答できるのは昨日アップした私の記事だけのはず。



要約もしっかり情報の取捨選択できている。この動作には驚きです。



# Chat-GPTでも確認してみよう





Chat-GPTは新しい情報を検索すると、学習データが古いから無理って回答していたはずなので同じ質問してみた。





まずは正解がある質問から。


> 質問：PowerShellでタスクトレイに常駐することができますか


![1000005094.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/0c38d55c-e95c-8355-1303-a7cf6e48e03f.png)



内容は正しそう。

私のQiita記事ではなく、違うソースで回答してますね。類似記事がネットにありますので、別の記事を学習しているようです。





続いて昨日アップした記事を想定した質問


> 質問：PowerShellでスクリーンショットを取得したい


![1000005095.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/0ad7d5d0-95ad-4efb-a6be-dca6a76dc215.png)


私の知らないAPIでスクリーンショット取得する方法を提示された。

私の記事に近づくように再質問してみる。


> 質問：ScreenCaptureというライブラリを使ってPowerShellでスクリーンショットを取得したい


![1000005096.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/f7f6ed31-e25b-eaa9-8530-3a348b67d437.png)



実在しなさそうなライブラリを使ったスクリプトが提示されました。

学習データが古いので私の記事には到達しなかったです。

知らないなりに頑張って回答してくれました。





# Copilotさんにどのような実装か聞いてみる



昨日の記事の内容を回答する動作が、どのような実装か想像つかなかったのでCopilotに聞いてみます。

あまりにすごいので敬語になっています。




> 質問：Copilotさんは昨日の記事の内容も回答できるのですごいです。昨日の記事も学習しているのですか？


> Copilot回答：私の知識は2021年までの情報に基づいていますが、それ以降の情報については、特定のツールを使用してウェブ検索を行うことで最新の情報を提供することができます。したがって、昨日の記事について具体的な情報が必要な場合は、その内容について具体的な質問をいただければと思います。それにより、私は最新かつ正確な情報を提供するためにウェブ検索を行うことができます。よろしければ、何を知りたいのか教えていただけますか？



学習していない情報は検索して回答しているようです。

検索した情報を要約して回答しているらしい。ディープラーニング技術の使い方がうまい。



あまりにすごいので、Copilotさんを褒めておきました。



> 質問：ディープラーニング技術とネット検索技術の組み合わせがシームレスですごいです


> Copilot回答：ありがとうございます！私の目指すところは、ユーザーの皆様が必要とする情報を効率的に、かつ正確に提供することです。ディープラーニング技術を用いて大量の情報から適切な回答を生成し、さらにネット検索技術を活用して最新の情報を取得することで、より広範で詳細な情報を提供できるようにしています。これらの技術の組み合わせにより、私はユーザーの皆様に対して、より有用でタイムリーな情報を提供することが可能となっています。これからもより良いサービスを提供できるように、引き続き努力してまいります。どんな質問でもお気軽にどうぞ！


# おわりに


CopilotもChat-GPTもそれぞれ特徴があって面白いですね。

Chat-GPTもGPT4等を使えばさらに賢いらしいので、機会があれば比較してみたいです。
Zig print関数の表記法(オプション設定)について

既にドキュメントがあった。
----
フォーマット形式の資料が以下にあった。

[zig.guideのAdvanced Formatting](https://zig.guide/master/standard-library/advanced-formatting)

調べた時はなかったので仕方がなくソースを見て理解したけど、無駄に終わっちゃった。


はじめに
----
Zig言語の動作を確認するためにprintを使用し、各データを確認している。
そのprintの表示について、調査したのでここに記述します。

version: 0.12.0
動作環境: MacOs
対象コード: [std/fmt.zig](https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig#L30)

print関数の定義
----
print関数には以下の二つの定義がある。

1. std.debug.printの定義

```
const std = @import("std");
const print = std.debug.print;
// --> io.getStdErr().writer().print
```
標準エラー出力を使っている。そして、エラーの戻りがない。
`io.getStdErr().writer()`を呼び出す前にthread間の排他制御(mutex)が入っているので、より安全になっているが、他のthread
と競合する場合があり注意が必要となる。

2. std.io.getStdOut().writer()からの定義

```
const std = @import("std");
const stdout = std.io.getStdOut().writer();
const print = stdout.print;
```
標準出力を使用で、エラー戻りがある。
従って、`try print(....)`とエラー処理が必要となる。


通常は*2.*の標準出力`stdout`を使用すべきだろうが、*1.* `stderr`を使用しているのが一般的となっている様だ。

オプション設定
-----

```
const message: [] const u8 = "print";
const data: u8 = 6;
print("{s} -> {d}: {b}\n", .{message, data, data});		// print -> 6: 110;
```

""の中の`{s}`など設定によりデータを表示する方法を変更する。

`{}`の内容は
```
	{[argument][specifier]:[fill][alignment][width].[precision]}
```
となっている。

1. argument - データのインデックス番号またはデータのフィールドで使われる引数の名前を指定する。
```
const message: [] const u8 = "print";
const data: u8 = 0x42;
print("{s} -> {d}: {1b}\n", .{message, data});		// print -> 66: 1000010 
```
`{1b}`の1が`{message, data}`のindex0,1の1を指し、dataを意味する。
引数の名前についてはまだわからない。

2. specifier - 表記方法を指定する。 例、{b}-バイナリー
	{x} - Hex(16進)表示で小文字 例1ffe 
	{X} - Hex表示で大文字 例1FFE 
	{s} - string表示 例 Hello world
	{e} - 浮動小数点の表示 例 1.234e3
	{d} - デシマル(10進)表示   例 1234
	{b} - バイナリー(2進)表示 例10001010
	{o} - octal(8進)表示 例 2322
	{c} - キャラクタ(Ascii) 1文字表示 例 H
	{u} - UTF-8表示　???
	{?} - `null` を含むデータを表示する
	{!} - Error コード表示
	{*} - アドレス表示
	{any} - 配列、構造体などのフォーマットとして定義された表示

3. fill - *width*で指定された文字幅内の空きにセットする文字

4. alignment - `<`:左寄せ、`^`:センター、`>`:右寄せで文字を詰める方向を指定

```
print("{b:0>8}", .{6});		// 00000110
```
`{b:0>8}`の0:fill,>:alignment、8:widthとなっている。つまり、文字幅を8桁で右詰、空きに0を満たす事となる

5. width - 表示する文字幅を指定する。

6. precision - 小数点以下の有効数字 
```
print("dat: {e:.3}\n", .{12.3456});		// 1.235e1
```

使用例
---

```
const std = @import("std");
const print = std.debug.print;

test "sample print function" {
    const deci: u16 = 0x1234;
    const flo: f32 = 12.345;
    const stri: []const u8 = "printing";
    
	print("{1s:<10} : d:{0d:5}\n", .{ deci, stri });	//  printing   : d: 4660
    print(" b:0b{0b:0>16} x:0x{0x:0>4}\n", .{deci});	//  b:0b0001001000110100 x:0x1234
    print(" e:{0e:<8} {0e:<8.3} {0e:<8.1}\n", .{flo});//  e:1.2345e1 1.235e1  1.2e1
}
```

最後に
----
現状、Zig言語はprint関数然り、どう使うかのドキュメントがない。そのため、ソースを確認したり実験により調査しました。
参考になれば幸いです。
Pythonで論理演算

# はじめに
前回から続いて論理演算をやってみます。
動作確認はGoogleColabpratoryで行っています。

# 論理和
```python
num = 10

num > 100 or num < 1000
```

# 論理積
```python
num = 10

num >100 and num < 1000
```

# 否定
```python
num = 10

not num > 1000
```
Arch Linux + Sway の環境構築で詰まったところメモ(随時更新)

swayはi3の設定をほぼそのまま引き継げてWaylandが使えるので使おうと思って環境を構築したがいくつか詰まった部分があるのでメモ
# LightDMだと動かない
おま環かもしれませんがLightDMでは動きませんでした。公式にはDisplay Managerはサポートしていないらしいですが`ly`だと動きました。
# xrandr, feh --bg-hoge は使えない
まあ当たり前ですが`xrandr`や`feh --bg-max`などは使えません  
.config/sway/configの方に直接設定を記入します
例:
```config:.config/sway/config
output HDMI-A-1 pos 0 0 bg ~/backgrounds/bg2.png fit
output eDP-1 pos 0 1080 bg ~/backgrounds/bg1.png fit
```
こっちの方が楽でよさげです。

# outputの設定の座標に負数を使うとXWaylandでマウスが効かなくなる
```config:.config/sway/config
output HDMI-A-1 pos 0 -1080 bg ~/backgrounds/bg2.png fit
output eDP-1 pos 0 0 bg ~/backgrounds/bg1.png fit
```
こんな感じで負の数を含む設定にするとXWaylandのバグ？でXWaylandのウインドウでマウス操作が聞かなくなります。  
これに引っかかって結構困っていました。

# Chromium系をWaylandネイティブで動かすとIMEが使えない
これも引っかかって困っていました。  
起動時のフラグに特に何もつけなければXWaylandの方で動くので問題ないです。

# fcitx, IBusは使えない
fcitx5を入れて解決しました。

# .xprofileが使えない
まあこれも当たり前ですが使えません。
私は`.xprofile`でIMEの環境変数を設定していたので`/etc/environment`で設定し直しました。
おそらく`.bash_profile`などでもよさそう？です。

# クリップボードの仕様が違う
`xsel`が使えません（それはそう）。`wl-clipboard`が必要です。

# スクリーンロック
`i3lock`の代わりに`swaylock`を使うとよいです。`swaylock-effects`でかっこいいエフェクトもつけられます。

# `i3bar`, `i3status`, `polybar` などの代替
waybarがかなりいい感じです。jsoncで設定ファイルを書いてcssでスタイルを変更できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/742a0285-be84-b342-1166-61e0cc560465.png)
こんな感じにできます。

# weztermが重い？（要検証）
weztermが急にフリーズしたりカクついたりするのでkittyを使っています

# 画面共有ができない
`v4l2loopback`をインストールしてカーネルモジュールをロードする必要があります。あと`xdg-desktop-portal`、`xdg-desktop-portal-wlr`も必要です。Discordのアプリ版だと画面共有ができなかったのでOBSの仮想カメラを使いました。


# 完成した環境
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/74d0366a-3d56-df3c-9e84-fadc3e2ef6a1.png)
Tokyo Night Stormで色を統一しています


# dotfiles
https://github.com/michirakara/dotfiles

# 環境構築時にお世話になった記事
https://zenn.dev/haxibami/articles/wayland-sway-install
WindowsでiOS Safariをデバッグしよう2024-2025

## 始めに
実はWindowsでもiOS(iPadOS) Safariのインスペクトができます。

[![BackspaceKeyにした投稿イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295995/231a4058-2228-1e92-bdd1-67fa5108113c.png)](https://misskey.flowers/notes/9svtmwzq87yn03tk)

[iwdp]:https://github.com/google/ios-webkit-debug-proxy
[iOS WebKit Debug Proxy][iwdp]と、任意のWebkitインスペクターを使ってインスペクトをする。
[iOS WebKit Debug Proxy][iwdp]のREADMEに非常に助けられた。ほとんどそれに従った。
ではやっていこう！

## 準備
以下の順番で進める。
1. yarnがインストールされていることを確認
1. Scoopをインストール
1. iOS WebKit Debug Proxyをインストール
1. iOSデバイスを設定、PCと接続
1. 任意のWebkitインスペクターフロントエンドを入手、使用

## Scoopインストール
パッケージマネージャーです。
```powershell:PowerShell
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
```
操作実行の権限を変えたい場合はSet-ExecutionPolicyを調べてください。以下にコマンドは書きますが調べたほうがいいです。
```posh:PowerShell
Set-ExecutionPolicy RemoteSigned -scope CurrentUser # 現在のユーザーの実行権限を緩くする
```


## [iOS WebKit Debug Proxy][iwdp]インストール
```posh:PowerShell
scoop bucket add extras # インストールできるアプリの範囲を広げる
scoop install ios-webkit-debug-proxy
```

### remotedebug-ios-webkit-adapterを入れるって記事が多いけど？
ChromeのDevToolsをどうにかして使うソフトですが、そのソフト、もう古くてメンテもされてないし、互換性ももうイマイチなので使うのはやめましょう。苦労するだけです。
iOS WebKit Debug ProxyのREADMEにも矛盾大きすぎって書いてあります（たぶんこれは直接プロキシーに接続する話かも）。
> In recent versions of Chrome and Safari there're major discrepancies between Chrome Remote Debugging Protocol and Webkit Inspector Protocol, which means that newer versions of Chrome DevTools aren't compatible with Safari.

## iOSデバイス設定
iOS 設定アプリ->Safari->詳細->Webインスペクタのスイッチをオンに
PCでiTunesを起動し、iOSデバイスとPCを**USBで**接続し、それぞれ相手を信用する操作をする。
iTunesのWi-Fi同期をオンにして試したがうまくいかなかった。

## 任意のWebkitインスペクター入手、使用
私は[webkit-webinspector](https://github.com/artygus/webkit-webinspector)を使いました。
```posh:PowerShell
ios_webkit_debug_proxy # プロキシーを起動
```
```posh:PowerShell
git clone https://github.com/artygus/webkit-webinspector.git # もしくはReleasesからダウンロードする
cd webkit-webinspector
yarn start
```

[localhost:9221](http://localhost:9221)にアクセスして端末を選び、任意のリンクのアドレスの`?ws=...`以降をコピー。
[localhost:8080/Main.html](http://localhost:8080/Main.html)にアクセスし、URLの最後にさっきコピーした文字列を貼り付ける。

> You can use the -f argument to specify different frontend source

とiOS WebKit Debug ProxyのREADMEに書いてあったのでそれに従って設定してみたが、僕が使ったインスペクターフロントエンドは読み込みが遅くなりすぎる不具合により使い物にならなかった。

## 終わりに
Windowsでもインスペクトができる！Mac miniを買わずに済みました。
工夫次第で、フリーでできることがわかりました。
みんなもやってみてね。

## 追記 2025年
[ios-safari-remote-debug-kit](https://github.com/HimbeersaftLP/ios-safari-remote-debug-kit)を利用、付属のREADMEを読んででもやってみた。
その時はWi-Fi同期ONのみでもうまく作業ができた。
やはりこちらのほうが、開発が新しいだけあって、快適に利用できるようになっていた。
今はこちらを利用したほうがよさそう。

### iOS WebKit Debug Proxyのフロントエンド指定の考察

> You can use the -f argument to specify different frontend source

というiOS WebKit Debug Proxyの機能は、今のWebKitインスペクターと比べてプロトコルが古いせいで使い物にならないのだろう。
現在、どんな外部フロントエンドも、別途HTTPサーバーを用意して利用するようになっている。
これでスキャン不要！商品が割引の対象かを商品コードでささっと判別！

ピチピチの社会人2年目
小売業界でお仕事をしています、rukq(ルカ)と申します！

現在、僕が担当している売場ではセールが開催中です。
その中でムリ・ムダ・ムラに気づいちゃいました！

それは...
**この商品は割引対象の商品なのか一目でわからない！**

以前までは割引シールが付いていて一目瞭然だったのですが、
今は自動で価格が変更される仕様ではタグを付けずにセールを行っているため、
見た目だけでは分かりません。
また、商品量が多く、自分が担当しているブランド以外は把握できていません。

この点を改善すべく今回もLINE botを作成しました！


## :robot:使用ツール
+ Make
+ Googleスプレッドシート
+ Chat GPT
+ GAS
+ LINE

## :robot:プレビュー

https://x.com/oktk_R/status/1795836946738290988

商品コードを送ると、その商品が対象かどうかと割引が適応された金額を送り返してくれます！

## Makeの構成！
![MAKE2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775363/e7cb83b2-33ed-4f18-2725-a72d0686f905.png)

今回もシンプルな構成となっております！
送られた商品コードがスプレッドシートに記載されている場合が上
記載されていないものが下に振り分けられます。

## :robot:モジュール中身！

今回もスプレッドシートを利用しました。
中身はこちらになります。
![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775363/83721e33-5e78-cf82-ddfc-a434c07817bc.png)


元のデータには割引適応価格は記載されていないため
今回はChat GPTで作った関数をGASで実行して値を求めました！

![@@@.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775363/12771390-cf9b-0e3e-75ff-5cce915888be.png)

商品コードと同じ数字をスプレッドシートから照らし合わします。

![@@@.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775363/4bdceef8-4ea1-00ce-17ab-12a68db704af.png)
同じものがあればこちらのフィルターを通ってメッセージが送られてきます。

![@@@.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775363/2137ad5a-c436-2b23-a7ad-865838a47b6d.png)
無ければこちらのフィルターを通ってメッセージが返ってくるようになっています。




## :robot:GASで利用したカスタム関数
![@@@.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775363/4c66c70d-bc11-09d4-634b-66ad80322770.png)
Chat GPTにこのように投げかけて関数を作ってもらいました！
こちらの関数を利用して20％オフなる金額を導き出しています。

## :robot:今回の振り返り
前回のプロトタイプではスプレッドシートを手動で入力していた。
しかし、今回はChat GPTで関数を作ってもらい。GASを利用することで時間の短縮につながりました！
空いた時間を利用して職場のメンバーに今回作ったLINE Botを触ってもらいました。

その際に次のようなコメントをいただきました。

**「いちいちスキャンチェックのためにレジに行く手間が省けて便利」**

**「こういった便利な機能がたくさん詰まったものが欲しい」**

好評だったのは非常に嬉しかったです！
また、前回のプロトタイプも含めて便利な機能を一つにまとめ、
十徳ナイフのようなLINE Botを作成したいと考え、モチベーションが高まっています！

今回はChat GPTを利用するには簡単すぎる作業だったかもしれませんが
この成功体験が今後の作成の糧になると思っています。
これからもたくさんチャレンジしていきます！
ここまで読んでいただきありがとうございました！
Docker-ComposeでGodot用のサーバーを立てようとした話（構築編）

## ブラウザゲームを作りたいから始まりました
とりあえずチュートリアルを終わらせてエディタをもちょもちょ触っていたところHTML5形式にエクスポートができることに気づく。
わし「あれ？Godotをフロントエンドにして、何かしらの言語でバックエンド作ったらブラウザで遊べるオンラインゲームが作れるんじゃあないかしら？」
とりあえずバックエンドは触ったことのあるPythonに白羽の矢が立つのであった。
初めて書く記事がこんなネタでいいのか？

## とりあえず環境構築
#### サーバーの環境はこちら
* Ubuntu 22.04 LTS
* Python3インストール済み
* サーバーが汚れるのを防ぐためDocker-Composeで専用コンテナを作りたい願望
* URLが「http://」で始まるのはなんかちょっとダサい気がしたので「https://」にあこがれる
* ApacheよりもNGinxの設定ファイルのほうが書きやすかった記憶があるのでNGinxでWebサーバをつくる

#### SSL 証明書を取得する
certbotを使用して証明書を取得する
```
apt -y install certbot
certbot certonly --standalone -d [NoIPあたりで取得したドメイン] -v
```
こんなものが作成されました
```
/etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/privkey.pem
/etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/cert.pem
```

#### docker-compose.ymlはこんな感じ
Docker-Composeって言うのを使うとサーバーを汚さずに破壊と創造ができるらしいので手を出してみた。
バージョンがなぜ3なのかを知らないままそれっぽい設定を記述していく。
なにやらVolumesに記載したものがコンテナ上に異世界召喚されるらしい。
○○○:△△△と書くとサーバー上の○○○というファイルをコンテナ上の△△△に召喚！
```
version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - "1010:1010"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl.conf:/etc/nginx/conf.d/ssl.conf
      - ./html:/usr/share/nginx/html
      - /etc/letsencrypt:/etc/letsencrypt:ro
    restart: always 
```
どうやらこう書くと
* バージョン：３（バージョンってなんぞ？教えてえらい人）
* コンテナ名：nginx
* イメージ：nginxを最新版で
* ポート：せっかくなのでデフォルトっぽい443を避けて1010
* 異世界転生するやつ
  * ./nginx.confというファイルを/etc/nginx/nginx.confへ
  * ./ssl.confというファイルを/etc/nginx/conf.d/ssl.confへ
  * ./htmlというディレクトリを/usr/share/nginx/htmlへ
  * /etc/letsencryptというディレクトリを/etc/letsencryptへ(ro:読み込み専用とのこと)
* サーバーの筐体を再起動しても自動でコンテナを起動してくれるらしいぞのおまじない

#### Nginxの設定ファイル
1.  nginx.conf
今後の拡張に期待してconf.dの中のconfファイルを片っ端から読み込むよという設定にする
```
events {}

http {
    include /etc/nginx/conf.d/*.conf;
}

```
2\. ssl.conf
```
server {
    listen 1010 ssl;
    server_name [NoIPあたりで取得したドメイン];

    ssl_certificate /etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/cert.pem;
    ssl_certificate_key /etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    # Cross-Origin-Embedder-Policyヘッダーを設定
    add_header Cross-Origin-Embedder-Policy "require-corp";

    # Cross-Origin-Opener-Policyヘッダーを設定
    add_header Cross-Origin-Opener-Policy "same-origin";
    
    include       mime.types;
    default_type  application/octet-stream;
    
    types {
        text/javascript js;
        application/javascript js;
    }
    
    location / {
        root /usr/share/nginx/html;
        index index.html;
    }
}


```

#### いざ起動
```
docker-compose up -d
```
立ち上がりはしたらしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255598/f693eec4-3ed9-8167-b518-eff418504d60.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255598/1321a801-ba5d-b187-e272-01670d5dbc4d.png)


次回へ続く！
https://qiita.com/typegarnet/items/0ef8431b061ad5bc74b4
要素の垂直位置の取得方法（JQuery↔︎Vanilla JS）

JQueryをVanilla JS(素のJavaScript)に書き換えている際、「あれ要素位置どうやって取得してたっけ...？」となったのでメモ。いい加減覚えたい。

## vanilla JS
### 絶対位置
- `window.pageYOffset` はページの垂直スクロール位置を返す
- `element.getBoundingClientRect().top` は要素のビューポートからの垂直位置を返す

```
window.pageYOffset + element.getBoundingClientRect().top
```

### ビューポートからの相対位置
```
element.getBoundingClientRect().top
```

## JQuery
### 絶対位置
- `element.offset()` はドキュメントの左上隅からの絶対位置を返す
- `.top` プロパティを使って垂直位置を取得

```
element.offset().top
```

### ビューポートからの相対位置
- `$(window).scrollTop()` は現在の垂直スクロール位置を返す

```
element.offset().top - $(window).scrollTop()
```

## イメージ
![要素位置の取得.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564152/6daa73a9-752d-3431-de31-ddb512564d1f.png)


## 補足
`window.pageYOffset;`　は古いブラウザ（IE9以下）ではサポートされていないため、以下のように記述することもある。
```
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
```
デュアルピボットクイックソートの仕組みと実装

## デュアルピボットクイックソートとは

デュアルピボットクイックソートは、従来のクイックソートの一種で、2つのピボットを使用することでソートを効率化します。これにより、パーティションの分割がより細かくなり、アルゴリズムのパフォーマンスが向上します。

### アルゴリズムの概要

1. **ピボットの選択**:
   2つのピボットを選択します。通常、配列の先頭と末尾の要素が使用されます。

2. **パーティショニング**:
   選択した2つのピボットを基準に、配列を3つの部分に分けます。
   - 左側の部分は、最初のピボットよりも小さい要素が含まれます。
   - 中央の部分は、2つのピボットの間の要素が含まれます。
   - 右側の部分は、2番目のピボットよりも大きい要素が含まれます。

3. **再帰的ソート**:
   分割された各部分に対して再帰的にデュアルピボットクイックソートを適用します。

### アルゴリズムの利点

- **パフォーマンスの向上**:
  デュアルピボットクイックソートは、2つのピボットを使用することでパーティショニングがより効率的になり、ソートのパフォーマンスが向上します。
  
- **安定性**:
  デュアルピボットクイックソートは不安定なソートですが、特定のケースでは安定性を保つことができます。

## 実装例

以下に、Javaでのデュアルピボットクイックソートの実装例を示します。

```java
public class DualPivotQuickSort {

    public static void dualPivotQuickSort(int[] arr, int low, int high) {
        if (low < high) {
            // ピボットの選択とパーティショニング
            int[] pivots = partition(arr, low, high);
            int pivot1 = pivots[0];
            int pivot2 = pivots[1];

            // 左部分の再帰的ソート
            dualPivotQuickSort(arr, low, pivot1 - 1);
            // 中央部分の再帰的ソート
            dualPivotQuickSort(arr, pivot1 + 1, pivot2 - 1);
            // 右部分の再帰的ソート
            dualPivotQuickSort(arr, pivot2 + 1, high);
        }
    }

    private static int[] partition(int[] arr, int low, int high) {
        if (arr[low] > arr[high]) {
            swap(arr, low, high);
        }
        int pivot1 = arr[low];
        int pivot2 = arr[high];

        int lt = low + 1;
        int gt = high - 1;
        int i = low + 1;

        while (i <= gt) {
            if (arr[i] < pivot1) {
                swap(arr, i, lt);
                lt++;
            } else if (arr[i] > pivot2) {
                swap(arr, i, gt);
                gt--;
                i--; // swapで入れ替わった要素を再度チェックする
            }
            i++;
        }
        lt--;
        gt++;

        swap(arr, low, lt);
        swap(arr, high, gt);

        return new int[]{lt, gt};
    }

    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr = {24, 8, 42, 75, 29, 77, 38, 57};
        dualPivotQuickSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
}
```

### コードの説明

- **`dualPivotQuickSort` メソッド**:
  - 配列とその範囲（`low`から`high`）を受け取り、ソートを行います。
  - `partition` メソッドを呼び出して、2つのピボットを基準に配列を3つの部分に分割します。
  - 各部分に対して再帰的にソートを行います。

- **`partition` メソッド**:
  - 配列を2つのピボットを基準に3つの部分に分割します。
  - 2つのピボットを選択し、それらを基準に要素を入れ替えながらパーティショニングを行います。
  - 最終的に、ピボットの位置を返します。

- **`swap` メソッド**:
  - 配列内の2つの要素を入れ替えます。

## まとめ

デュアルピボットクイックソートは、従来のクイックソートを改良した効率的なソートアルゴリズムです。2つのピボットを使用することでパーティショニングを効率化し、パフォーマンスの向上を図ります。
Snowflake NotebooksでSQLを実行するウェアハウスを変更する、あと注意事項

## Snowflake Notebooks

Snowflake NotebooksはSnowflakeのWeb UIであるSnowsight上で提供されている開発環境です。SQL、Python、Markdownを一つのノート上に混在して記述できるのが特徴です。  
雰囲気的にはJupyter Notebookのようなサービスになっています。  

![Snowflake Notebooks](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/6c3b6253-d6a3-0755-a2d4-1fd38048f813.png)

先日2024/5/25にPublic Preview (PuPr)されました！(2024/5/30時点では公式アナウンスなし)  

## SQLを実行するウェアハウスを変更する

ノートブックの実行にはウェアハウス[^1]が必要になります。  
クレジットが消費されるのでできるだけ小さいものを指定して節約することになるのですが、ノートブック内に重いクエリがあるときに時間がかかってしまいます。  
そういうときは単純に```USE WAREHOUSE```コマンドでウェアハウスを切り替えればいいようです。  

[^1]: 仮想ウェアハウス。Snowflakeで色々な処理を行ってくれるコンピューティングのこと。

![example](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/3fc5b64f-fde7-31ba-f2cd-ace21e2d803c.png)

上記の例では```USE WAREHOUSE FROSTYFRIDAY_WH_LAAAAAARGE;```を実行することで、ウェアハウスが切り替わっています。  
また、ノートブックそのものの実行で使われるウェアハウスは切り替わっていないことが確認できます。  

次のセルでも前のセルで設定したウェアハウスがそのまま使われているので、ここは注意が必要そうです。  
~~一方で「特定のPythonセルだけ強いウェアハウスを使いたい！」という場合もあるので、そういうときにはSQLセルでウェアハウスを切り替えてから次のPythonセルで重い処理をやらせる、ということをやればよさそうです。~~

Pythonセルでウェアハウスを切り替える場合は以下のようにします。力業だ。  

```py
session.sql("USE WAREHOUSE (ウェアハウス名);")
```

ただし、SQLセルやPythonセルで切り替えたウェアハウスはSQL文の実行およびSnowpark DataFramesの操作[^3]にのみ使われるようです。  
Pythonセルに含まれるSnowpark DataFramesの操作以外のコードの実行はノートブックそのものの実行と同じウェアハウスが使われます。  
そのため、Pythonセルで重い処理をやりたい場合は

- ノートブックそのものを強いウェアハウスで実行する。ただしコストは割高になる
- その重い処理をSnowpark DataFramesの操作に置き換えられないか考える

必要があります！

[^3]: Snowpark DataFramesの操作は、裏側ではSQL文に変換してから実行されます。

### 管理画面上ではどうなっているのか

ノートブックそのものの実行は```execute notebook```という形でログが出力されています。  

![admin1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/befc1e40-2fa1-67c1-0643-cd0797cd6e1b.png)

上記の例で切り替えたウェアハウスの方を確認してみると、こちらにはクエリを実行したログのみが出力されていることが確認できます。  

![admin2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/8431264e-3996-abcf-b0fc-29455c9a14d1.png)

## 注意事項

ノートブックは表示している間、ウェアハウスが起動したままになってしまうため、じわじわとクレジットを消費します。  
ユーザが何も操作しないアイドル状態が続くとウェアハウスが停止するのですが、そのタイマーが60分間とかなり長めに設定されています。[^2]

[^2]: 2024/5/30時点

![warning](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/ed3ec12f-05a4-747b-93ee-0966279dcc69.png)

ウェアハウスは、  

- 右上のボタンから「セッションを終了」を選ぶ  
- ノートブックのページを閉じる  
- アイドル状態が60分間続く  

のどれかが発生すると停止します。

- ノートブックを開いて、数分おきにクエリを実行していたら、いつの間にか最初に開いてから60分間経過していた  

という場合は停止しません。  

ワークシートのノリで開いたまま放置してしまいそうなので、こまめにセッションを終了して節約していきましょう。
Ubuntuでシェルスクリプトを作成・実行する方法

## シェルスクリプトの作成
まず、シェルスクリプトを作成します
まず、スクリプトを作りたいフォルダに移動して、
開いてるところで 右クリック→新しいドキュメント→空のドキュメント で、
ドキュメントファイルを作成します。（画像はファイルを作成したあとの様子）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691296/7bf8e76a-faa9-c908-7728-a767a6dabe9f.png)

そして、ファイルを 右クリック→テキストエディタで編集 で編集していきます

試しに、HelloWorld!と表示するスクリプトを書いてみましょう！

以下のテキストをそのまま貼り付けて保存してください
```
#!/bin/sh

echo "HelloWorld!"
```

そしたら、ファイルのプロパティを開き、「Executable as Program」をONにして閉じます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691296/a5dd261a-ca9d-338e-43b0-75db49dfdd8c.png)

そして、ターミナルを開き、フォルダに移動して、
「./空のドキュメント」で実行できます
SVGのサイズを指定する方法

## はじめに

SwiftUIではタブに使う画像のサイズをプログラム上から変更できません。

```swift
TabView {
    Text("Foo")
        .tabItem {
            Text("iOS Osushi")
            Image(.tabOsushi)
                .resizable()
                .frame(width: 31, height: 31) // !!!: 効かない
        }
}
```


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/0a957a70-fff2-4267-91a6-75bb0089825b.png" width=400>

そのためSVGファイルを更新する必要があるのですが、サイズを指定する方法がわからなくて調べたので紹介します。

## SVGのサイズを指定する

SVGをNeovimなどのテキストエディタで開き、 `width` と `height` を追加するだけです。

```diff_xml:tab_osushi.svg
<?xml version="1.0" encoding="UTF-8"?>
- <svg id="_レイヤー_1" data-name="レイヤー 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
+ <svg id="_レイヤー_1" data-name="レイヤー 1" xmlns="http://www.w3.org/2000/svg" width="31px" height="31px" viewBox="0 0 400 400">
...
```

これだけでSVGのサイズを指定できます。

```diff_swift
TabView {
    Text("Foo")
        .tabItem {
-             Text("iOS Osushi")
-             Image(.tabOsushi)
-                 .resizable()
-                 .frame(width: 31, height: 31) // !!!: 効かない
+             Label("iOS Osushi", image: .tabOsushi)
        }
}
```


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/0dad9524-55ce-7931-458b-bf3286a7bc76.png" width=400>

## おわりに

SVGのサイズを指定する方法でした。
XMLを直接書き換えるのが少し不安なので、もっといい方法を知っている方がいたら教えてくださると嬉しいです :relaxed:

## 参考リンク

- [Resizing .svg image using 'convert' function of ImageMagick suite produces empty images - Stack Overflow](https://stackoverflow.com/questions/43522939/resizing-svg-image-using-convert-function-of-imagemagick-suite-produces-empty)
- [TabView | Apple Developer Documentation](https://developer.apple.com/documentation/swiftui/tabview)
名前解決が急に出来なくなった話

# はじめに

これは私の家で急に内部の名前解決は出来るのに、外部名前解決が出来なくなった話です。  
結論から言うと、UDM-SEの広告ブロックが原因でした。

## 幣宅環境

- メインルーター
    - UDM-SE
- DNSサーバー
    - WindowsServer2019

## 事件詳細

ある日突然、外部の名前解決が出来なくなりました。  
UDM-SEのインターネットのDNS設定を自動にしたら、次は内部の名前解決が出来なくなりました。

### 対象サーバーの死活確認

最初にやったのは対象サーバーの死活確認。サーバーというかUDM-SEのWeb画面へ行こうとしました。  
インターネット見れているので問題なし。

### DNSサーバーの確認

DNSサーバーの死活確認。しかし、問題なし。

### クライアントPCでのnslookup

PCでnslookupをしてみる。

```
>nslookup
既定のサーバー:  UnKnown
Address:  172.16.1.105
```

・・・ん？
そもそもDNSサーバーへアクセス出来ていない。

### DNSサーバーへのUDP53疎通テスト

ChatGPTの力を借りて、DNSサーバーへのudp53が疎通できるかテストするコードを作ってもらう。

```powershell
function Test-PortUDP {
    param (
        [string]$ComputerName,
        [int]$Port,
        [int]$Timeout = 1000
    )

    $endpoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Any, 0)
    $udpClient = New-Object System.Net.Sockets.UdpClient
    $udpClient.Client.ReceiveTimeout = $Timeout

    try {
        $sendBytes = [System.Text.Encoding]::ASCII.GetBytes("Test")
        $udpClient.Connect($ComputerName, $Port)
        $udpClient.Send($sendBytes, $sendBytes.Length)

        $response = $udpClient.Receive([ref]$endpoint)

        if ($response) {
            return $true
        }
    } catch {
        return $false
    } finally {
        $udpClient.Close()
    }

    return $false
}

# 使用例
Test-PortUDP -ComputerName "172.16.1.105" -Port 53
```

結果はfalse


### DNSサーバーと同じVLANから名前解決

これは問題なし。
つまり同セグは大丈夫。

### 別VLANからの名前解決

NG
つまりVLAN間がNG

### UDM-SEからの名前解決

UDM-SEはLinuxベースで作成されているため、SSHログインするとLinuxコマンドが使えます。  
そのため、digコマンドを実行したところ、問題なく解決。

……これはUDM-SEが原因と仮定

### 公式ドキュメント閲覧

Unifiは設定が比較的簡単ですが、ドキュメントがかなり少ないのが欠点。
そんな中、ドキュメントを読み漁ったところ、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1675077/5e801b2d-690c-c449-251b-314e6de0c82e.png)

早速、UDM-SEの設定を確認したところ、広告ブロックの適用ネットワークにServerSegmentのネットワークを発見。
速攻で無効化したところ、無事解決。

### 事件の原因

- 外部名前解決が出来なくなったの原因
    - 広告ブロックの対象にServerSegmentを追加したから
    - DNSサーバーが外部名前解決しようフォワード先にアクセスしようとしたら、UniFi Gateway DNSサーバーにリダイレクトされてしまっていた
- 内部名前解決が出来なくなった原因
    - UnifiのインターネットのDNS設定を自動（外部のDNSサーバー）にしたため

## 終わりに

Unifiはドキュメント少ないので、少しでも誰かの力になれば幸いです。
あと、何でもかんでもよく調べずに機能を使うのはやめよう。
Power Apps で図を回転させる方法

## 緒言
[JPPGBゲームコンテスト](https://jppgb.connpass.com/event/317001/)に無謀ながら挑戦する中で、画像回転させる必要性に迫られました。最初は`Image`コントロールでSVGを使う方法にしてましたが、iPhoneのみ挙動が変だったので最終的に`HTML TEXT`コントロールを使う方法で実装しました。[こちらの記事](https://zezeze.hateblo.jp/entry/2021/06/11/162858)を参考にさせていただきました。ありがとうございます！

## 方法
数式の表記はXでの↓のポストを参考にさせていただきました。便利！感謝！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/f777ed42-4355-000d-f4d3-d0ceec9a1b0b.png)

`HTML TEXT`コントロールの`HtmlText`プロパティを↓のような感じに。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/dc536888-76c8-c89c-ea2d-7704854e4115.png)

`margin-top`と`margin-left`は画像をセンタリングさせるために設定。
<strong>"base64画像データ"</strong>はどこか適当なサイトで画像を変換しておいて、App.Formulasで変数(定数？)として定義しました。もっとスマートな方法ありそう。。。

元画像の長辺が幅方向なら`width`で、縦方向なら`height`でサイズ指定。

`transform:rotate(数値deg)`で回転指定できる。

あとは回転させた時に`HTML TEXT`コントロールのサイズから画像がはみ出してしまわないように注意(はみ出すとスクロールバーが出てきて邪魔)。

`SLIDER`コントロールと連携させたりすると↓のような感じに。
![無題の動画 ‐ Clipchampで作成.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/99e96505-ee5d-64eb-b2fd-081cf93a101d.gif)
VSCodeの　Unknown at rule@tailwindの解決方法

tailwindcssを使ったプロジェクトにおいて，．cssファイルにtailwindのディレクティブを下記のように追加する必要があります．

```javascript:index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

が，これに対してvscodeから警告されることがあります．
（ちなみに@〇〇はアットルール(At-rule)と呼ばれ，cssの動作を規定します）


## 解決の手順
vscode自体は，そもそもtailwindcssのことを知りません．ですから，tailwindcssの拡張機能をvscodeにインストールした上で，少しだけ設定を行う必要があります．

以下の順番で進めます
1\.　VSCode（Cursor）に拡張機能　「Tailwind CSS IntelliSense」をインストール
2\. プロジェクトのルートディレクトリ配下に.vscodeディレクトリを作成
３\. .vscode内に，下記のようなsettings.jsonファイルを作成

公式ドキュメントはこちら

https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss


私のケースでは
プロジェクトフォルダ内に.vscodeディレクトリを作成し，その中に下記のsettings.jsonを作成することで解決しました．

注意：　ファイル名は「**settings.json**」です！（setting.jsonは❌）

```json:settings.json
{
    "files.associations": {
      "*.css": "tailwindcss"
    },
    "editor.quickSuggestions": {
      "strings": true
    }    
}
```

⬇️ディレクトリの構成はこんな感じ
![スクリーンショット 2024-05-29 21.16.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782784/94b466ca-aa58-740c-a6b0-d5346bb71113.png)




## 補足
### .vscode（ディレクトリ）とは？
プロジェクト内のみ適用される固有のvscode設定ができる．
下記のケースで有効
+ プロジェクトに固有のvscode設定を適用したい
+ グローバルのvscode設定を変えたくない

https://memorandom.whitepenguins.com/posts/tailwind-atmark-error/
AWS EC2サーバ作成

## EC2
Amazon Elastic Compute Cloud (Amazon EC2) は、Amazon Web Service (AWS) クラウドでオンデマンドのスケーラブルなコンピューティングキャパシティーを提供します。
Amazon EC2 を使用すると、必要な数 (またはそれ以下) の仮想サーバーの起動、セキュリティおよびネットワーキングの構成、ストレージの管理ができます。
## EC2サーバの作成
管理コンソールのサービスからEC2を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/2635459a-512d-bd41-6a82-b8e02fee1910.png)
EC2ダッシュボードのメニューインスタンスをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/36d84607-7e3c-1423-c6e1-9e35afe85bf4.png)
インスタンスを起動のボタンを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/259b42ad-69bd-f98c-fd0d-c1d918d52a9d.png)
### EC2インスタンスを作成
名前：my-ec2-02
OSイメージ：Amazon Linux 2023 AMI
インスタンスタイプ：t2.micro
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/3ee65e89-cbba-6520-c27c-cdac9187a342.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/160e553c-9cf8-ee56-9c73-5cb44899a9c8.png)
### キーペア：新しいキーペアの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/845dff32-c885-c70d-e8ba-2034092092ef.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/c27a8581-9bca-193f-a179-591c2c149e24.png)
### ネットワーク設定
VPC：my-vpc-01
サブネット：my-pub-subnet-01-1a
パブリック IP の自動割り当て：有効化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/fb7b965c-3cb2-b665-61ce-272a3853821c.png)
### ファイアウォール (セキュリティグループ)
セキュリティグループを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/e6f4a102-e59a-42b5-5b87-c5b15d7593a8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/0ca8e2c5-f2df-2075-dbcd-56b61ba2f0cc.png)
### ストレージを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/2b3740f0-1cbf-4a0f-2db6-797220eb59bd.png)
インスタンスを起動のボタンを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/3502d82e-88f6-a5f7-aee1-715629f4224c.png)
### EC2インスタンス起動を確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/3cb42bc7-ed7b-a491-3925-eac7340fee93.png)
SSHでEC2インスタンスに接続
ホスト：パブリック IPv4 アドレス
サービス：SSH
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/8d651546-907d-93bb-402a-126d2d7876a6.png)
セキュリティ警告：続行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/08ad7f2c-6697-0828-aecb-eefa4887c7bb.png)
ユーザ名：ec2-user
認証方式：RSA鍵
秘密鍵：ダウンロードしたキーペア
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/1551a827-adf4-07c4-1b2a-1bfa8ac73728.png)
接続できたことを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/b1e6992d-601a-2d57-f847-f8cd1864bb9e.png)
クラスタリングでラベリングして分類

クラスタリングは教師なし学習の中で集合に対してラベリング処理を行います。
そこで、クラスタリングの結果をクラスとして、それを元に教師あり学習をやってみようという原始的なアノテーションをやってみます。
# 関数
```Python3
from sklearn import preprocessing
import matplotlib.pyplot as plt
import numpy as np
def showline_clf(x, y, model, modelname, x0="x0", x1="x1"):
    fig, ax = plt.subplots(figsize=(8, 6))
    X, Y = np.meshgrid(np.linspace(*ax.get_xlim(), 1000), np.linspace(*ax.get_ylim(), 1000))
    XY = np.column_stack([X.ravel(), Y.ravel()])
    x = preprocessing.minmax_scale(x)
    model.fit(x, y)
    Z = model.predict(XY).reshape(X.shape)
    plt.contourf(X, Y, Z, alpha=0.1, cmap="brg")
    plt.scatter(x[:, 0], x[:, 1], c=y, cmap="brg")
    plt.xlim(min(x[:, 0]), max(x[:, 0]))
    plt.ylim(min(x[:, 1]), max(x[:, 1]))
    plt.title(modelname)
    plt.colorbar()
    plt.xlabel(x0)
    plt.ylabel(x1)
    plt.show()
```

# プログラム
## クラスタリング
### ライブラリのインポート
```Python3
from sklearn.datasets import make_blobs
from sklearn.svm import SVC
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
```
### アノテーションされていないデータを可視化
```Python3
x, y = make_blobs(n_samples=300, centers=4, random_state=0, cluster_std=1.0)
plt.scatter(x[:, 0], x[:, 1])
plt.show()
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/1e157517-65f2-3256-568d-3a73d7c73c98.png)
centerを4と設定している事は一旦置いといて、とりあえず4つ集合があるように見えますね。
### k-means法で4つラベリング
```Python3
km = KMeans(n_clusters=4)
km.fit(x)
y_pred = km.predict(x)
plt.scatter(x[:, 0], x[:, 1], c=y_pred, cmap="brg")
plt.show()
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/a9f591a8-bab0-03b3-ddcf-b19cfcd1d341.png)

データにラベリングされました。
### SVMで分類
```Python3
svm = SVC(kernel="linear")
svm.fit(x, y_pred)
showline_clf(x, y_pred, svm, "K-means -> SVM", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/4f815675-6ffd-972c-03b1-3425944aab54.png)

これによって次回からはSVMを使って随時新しいデータが出た場合は分類すれば大丈夫になりました。

# ただし
ただしこれが正しいアノテーションとは限りませんのでそこは疑いましょう。あくまでもクラスタリングの使い道の一つに過ぎません。
【VSCode】ターミナルの上部に現在のコマンドを表示する方法

`settings.json` に以下の設定を追記するとターミナルのスティッキースクロールが有効になり、長い出力でも常に上部に現在のコマンドが表示されるようになります。

```json:settings.json
  "terminal.integrated.stickyScroll.enabled": true

```

![スクリーンショット 2024-05-29 23.41.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/92649ca7-f64b-fe7c-acbe-1b265a681354.png)
Power Platform のテナント移行について

時々お客様からご相談いただく Power Platform のテナント移行について、すでに [MS Learn](https://learn.microsoft.com/ja-jp/power-platform/admin/move-environment-tenant?tabs=image) や [サポートブログ](https://jpdynamicscrm.github.io/blog/powerplatform/T2T-Introduction/) のほうに書いてありますが、改めて頭の整理のためにいくつかポイントを書いておきます。

## 実稼働環境・サンドボックス環境はSRにてMicrosoftが対応
これらDataverse有りの環境については、Microsoftのサポートチームにて移行対応します。実際には、環境は物理的に移動されるのではなく、別のテナントに関連付けられる形になります。
※移行元テナントに環境は存在したままになりますが、その環境は利用できなくなり、移行先テナントにて使用および管理できるようになります。

なお、移行先にも移行元と同じ量（もしくはそれ以上）の Power Apps Premium ライセンス や Dataverse キャパシティ が必要なので事前に確認ください。

また、移行されないリソースなどもあるため、事前にリハーサルを行っておくことをお勧めします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/cb7315b7-7842-0c87-4319-dde89b6be0cd.png)

## 既定の環境やDataverse for Teams環境はお客様で対応
Dataverseがプロビジョニングされている前提で、ソリューションで対応するのが基本的な対応になると考えられます。移行元でソリューションをエクスポートし、移行先にインポートしていきます。これ以外にもデータ移行の観点では、ExcelやSPOなどのデータソースがあったりするのでアプリの設定など修正が必要になってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/1764f87d-f9f9-0bdf-e871-6454692b053e.png)

作業のステップとしては、ざっくりと以下になるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/4e73888c-f4a2-6de1-984e-ad21fa3dc068.png)

とはいえ、ソリューション化やデータ移行など難しいテーマも含まれるため、すべての市民開発者にこうした対応を取ってもらうのは現実的には難しい話があるかと思います。定期的な棚卸（xx日以上使われてない、〇〇人にしか共有・使用されてない、似たようなアプリがある）を行っていただきながら、市民開発者に対して一定の移行ガイドライン・タイムラインを示していく必要があるでしょう。

## 移行元と移行先のテナントにおけるDLPポリシーの確認
環境内のリソースは移行できたとしても、DLPポリシーがテナント間で異なれば、移行先でコネクタが期待通りに動かない可能性があります。

## アプリやフロー内でハードコードされている変数の確認
適切に環境変数を使いつつ、ソリューションチェッカーを通して確認するなどが有効かと思います。
Appium関連一式をUpdateする

# はじめに
Appiumを使ってAndroid上のChromeアプリを操作するPythonコードを書いていたのですが、開発途中で急に動作しなくなりました。
「Chrome Driverの最新版が見つからない」的なエラーが出たいので、Appium、uiautomator2、Appium-Python-Clientをupdateします。

# Update手順
## Appium
```bash
$ npm i -g appium
```
## uiautomator2
```bash
$ appium driver update uiautomator2
```
## Appium-Python-Client
```bash
$ pip install -U Appium-Python-Client
```

以上で、Chromeアプリを操作できるようになりました。

# 参考
https://www.seleniumqref.com/introduction/tips/appiumIns_update.html
プロジェクト資源もプロジェクトの一つ

# はじめに
プロジェクトを成功へと導くために必要な資源、プロジェクト資源マネジメントについてメモしていきます。

## プロジェクト資源マネジメントについて

プロジェクト資源マネジメントとは、プロジェクトで必要となる資源の洗い出し及び、調達から管理まで一連の活動のことです。
ここでいう資源とは大きく分けて「人的資源」と「物的資源」があります。

### 資源マネジメントの進め方

1. 資源マネジメントの計画
プロジェクトを成功に導くにはどのような資源が必要で、どうやって調達するかなどの方針を定義するプロセスです。
資源マネジメントの計画では資源マネジメント計画書を作成します。この計画書には組織図や資源計画、役割担当計画といった内容が記載されます。

2. アクティビティ資源の見積もり
プロジェクトで発生するタスクを洗い出すことでプロジェクトで発生する資源を見積もるプロセスです。
必要となる資源について、どれくらい必要か、どこから調達するかを見積もります。

3. 資源の獲得
プロジェクトに必要となる資源を実際に調達します。
プロジェクトによっては外部から人員を確保することもあります。

4. チームの育成
チーム全体の協調性につながるような育成も含めることによってパフォーマンスの向上を目指します。プロジェクトの成果物の品質を高めることにつながります。

5. チームのマネジメント
チームのパフォーマンスを管理するプロセスです。
目標の共有や進捗状況の追跡から必要に応じて調整を行う必要があります。

6. 資源のコントロール
調達した資源が適切に使用されているかどうかを管理します。
「人的資源」であればプロジェクトメンバーの適材配置がされているか、「物的資源」であれば材料が予定通り使用されているか、などを管理します。

プロジェクト資源マネジメント含めプロジェクトでは明確な目標設定や継続的な改善につなげる必要があります。