masalibの日記 (original) (raw)

やましい事はしていないのですが とあるサイトのとある数値をエクセルにコピペしたいです。

プログラマーなのでpythonスクレイピングすればいいのですが もちろん禁止されているというか許可されていないので一個一個コピーして貼り付けています。 その対象のサイトはなぜかコピペができないようになっています。デベロッパーツールでコピーもできるのですがそもめんどくさい。普通のサイトと同じでコピペしたいのです。

右クリックを禁止を以下のサイトを参考に解除しました。
ただ毎回、打つのがめんどくさいの自動化しました

https://www.omakase.net/blog/2022/05/lift-migiclick.html

対象ブラウザ
chrome

対象サイト
とあるサイト.com

指定したJavaScriptコードを自動的に実行するために、 ブラウザの拡張機能を使います。Chromeでは、拡張機能を作成して、特定のサイトにアクセスした際に自動でスクリプトを実行させることができます。

  1. 拡張機能マニフェストファイルを作成する manifest.json という名前のファイルを作成し、以下のような基本的な設定を記入します:

    { "manifest_version": 3, "name": "Context Menu Blocker", "version": "1.0", "permissions": ["scripting", "activeTab"], "background": { "service_worker": "background.js" }, "action": { "default_popup": "popup.html", "default_icon": { "16": "icon16.png", "48": "icon48.png", "128": "icon128.png" } }, "content_scripts": [ { "matches": [""], "js": ["content.js"], "run_at": "document_start" } ] }

この設定では、全てのURLにマッチするcontent_scriptsを指定していますが、 必要に応じて特定のドメインに限定することも可能です。

  1. バックグラウンドスクリプトを作成する background.js というファイルを作成し、必要なスクリプトをバックグラウンドで実行させます。この例では、実際には特に何も書く必要はありませんが、拡張機能全体の設定の一部として含める必要があります。
  2. コンテンツスクリプトを作成する content.js という名前のファイルを作成し、そこに元のJavaScriptコードを入れます:

document.addEventListener('contextmenu', function(e) { e.stopPropagation(); }, true); window.onload = function() { document.querySelector("body").addEventListener("copy", function(event) { event.stopPropagation(); console.log("copy event delete"); }, true); };

  1. ポップアップHTMLを作成する簡単な操作を提供するためのpopup.htmlを作成します。これは拡張機能をクリックした時に表示される小さなHTMLページです。
  2. アイコンを用意する icon16.png, icon48.png, icon128.pngといったアイコンを用意し、それをマニフェストファイルで指定します。
  3. 拡張機能をインストールする Chromeブラウザで chrome://extensions/ にアクセスし、右上の「デベロッパーモード」をオンにして、「パッケージ化されていない拡張機能を読み込む」をクリックします。 そして、拡張機能のファイルが保存されているフォルダを選択します。
    めんぐさい人は以下のファイルをダウンロードして
    適当なフォルダに展開してそのフォルダを選択してください
    https://drive.google.com/file/d/1iORlmc1X9OfHQpJocDy7TCS5CteuLGnt/view?usp=sharing

大量にあるとプログラム一覧を作ることですら大変です。 ちょっとでも楽をするためにプログラム一覧をエクセルにするプログラムを作りました

事前作業

1 . Tree: ディレクトリのツリー構造を表示するためのコマンドラインツールです。ターミナルで treeコマンドを実行すると、カレントディレクトリ以下のディレクトリとファイルが階層構造で表示されます。Macにはデフォルトでインストールされていないことがありますが、Homebrewなどのパッケージマネージャーを使ってインストールすることができます。

brew install tree

インストール後は、tree コマンドでディレクトリ構造を簡単に表示できます。

2 . openpyxl: openpyxlpythonでエクセルファイルを作成するときに使用します

pip install openpyxl

pipが入っていない場合

python3 -m pip install openpyxl

出力

treeコマンドで出力するだけです

cd Projectフォルダ tree > tree_output.txt

出力結果をエクセルにする

import os from openpyxl import Workbook

def parse_tree_output(file_path): with open(file_path, 'r', encoding='utf-8') as f: lines = f.readlines()

parsed_lines = []

for line in lines:
    
    cleaned_line = line.lstrip().replace("├──", "").replace("└──", "")

    
    pipe_count = cleaned_line.count("│")
    indent_level  = pipe_count + 1

    
    cleaned_line = cleaned_line.replace("│", "").replace(" ", "").replace(" ", "")
    

    parsed_lines.append((cleaned_line.strip(), indent_level))

return parsed_lines

def write_to_excel(data, excel_file): wb = Workbook() ws = wb.active ws.title = 'Tree Output'

for line, indent_level in data:
    

    ws.cell(row=ws.max_row + 1, column=indent_level + 1, value=line)

wb.save(excel_file)
print(f"Excel file '{excel_file}' created successfully.")

if name == "main": tree_file_path = 'tree_output.txt'
excel_file_path = 'tree_output.xlsx'

parsed_data = parse_tree_output(tree_file_path)
write_to_excel(parsed_data, excel_file_path)

このスクリプトでは、parse_tree_output 関数で tree_output.txt ファイルを読み取り、各行のインデントレベルとパスを抽出します。 その後、create_excel_from_tree_output 関数で、取得したデータを新しいエクセルファイルに書き込みます。エクセルファイルは現在のディレクトリに tree_output.xlsx として保存されます。

不格好ですが加工しやすくなりました

私はobjective-cの初心者です。デバックしならがら引き継ぎしたソースを解析しています 以下のエラーがでました

パターン1

[self performSegueWithIdentifier:@"XXXXXView" sender:nil]; -[UIViewController performSegueWithIdentifier:sender:] must be used from main thread only

このエラーは、UI操作(特にSegueの実行)はメインスレッド(MainThread)で行う必要があるということを示しています。iOSアプリケーションでは、UI操作は常にメインスレッドで行われる必要があります。

エラーメッセージ [self performSegueWithIdentifier:@"XXXXXView" sender:nil]; がメインスレッド以外から呼ばれている可能性があります。これを修正するには、次のようにしてください:

メインスレッドでUI操作を行うUI操作を行う部分をメインスレッドで実行するように修正します。Objective-Cでは、次のようにdispatch_asyncを使って行うことができます:

   dispatch_async(dispatch_get_main_queue(), ^{
       [self performSegueWithIdentifier:@"XXXXXView" sender:nil];
   });

このエラーはなるほど・・・と思った

パターン2

以下のエラーはまじで意味がわからない

Main Thread Checker: UI API called on a background thread: -[UIViewController performSegueWithIdentifier:sender:] PID: 12095, TID: 4733842, Thread name: (none), Queue name: com.apple.root.default-qos, QoS: 0 Backtrace: 4 ApplicationName 0x0000000104971b70 -[XXXXViewController didFinishChkPrice] + 72 5 ApplicationName 0x000000010497b860 -[StoreKitManager finishChkPrice] + 116 6 ApplicationName 0x000000010497a70c -[StoreKitManager productsRequest:didReceiveResponse:] + 376 7 StoreKit 0x00000001baecf3b8 F2CA7CCD-9558-3093-AADB-3353C09DD93C + 115640 8 libdispatch.dylib 0x0000000105958b98 _dispatch_call_block_and_release + 32 9 libdispatch.dylib 0x000000010595a7bc _dispatch_client_callout + 20 10 libdispatch.dylib 0x000000010595d30c _dispatch_queue_override_invoke + 1056 11 libdispatch.dylib 0x000000010596eae4 _dispatch_root_queue_drain + 404 12 libdispatch.dylib 0x000000010596f4d8 _dispatch_worker_thread2 + 188 13 libsystem_pthread.dylib 0x00000001eea138f8 _pthread_wqthread + 228 14 libsystem_pthread.dylib 0x00000001eea100cc start_wqthread + 8 Main Thread Checker: UI API called on a background thread: -[UIViewController performSegueWithIdentifier:sender:] PID: 12095, TID: 4733842, Thread name: (none), Queue name: com.apple.root.default-qos, QoS: 0 Backtrace: 4 ApplicationName 0x0000000104971b70 -[XXXXXXXXViewController didFinishChkPrice] + 72 5 ApplicationName 0x000000010497b860 -[StoreKitManager finishChkPrice] + 116 6 ApplicationName 0x000000010497a70c -[StoreKitManager productsRequest:didReceiveResponse:] + 376 7 StoreKit 0x00000001baecf3b8 F2CA7CCD-9558-3093-AADB-3353C09DD93C + 115640 8 libdispatch.dylib 0x0000000105958b98 _dispatch_call_block_and_release + 32 9 libdispatch.dylib 0x000000010595a7bc _dispatch_client_callout + 20 10 libdispatch.dylib 0x000000010595d30c _dispatch_queue_override_invoke + 1056 11 libdispatch.dylib 0x000000010596eae4 _dispatch_root_queue_drain + 404 12 libdispatch.dylib 0x000000010596f4d8 _dispatch_worker_thread2 + 188 13 libsystem_pthread.dylib 0x00000001eea138f8 _pthread_wqthread + 228 14 libsystem_pthread.dylib 0x00000001eea100cc start_wqthread + 8

+[UIView setAnimationsEnabled:] being called from a background thread. Performing any operation from a background thread on UIView or a subclass is not supported and may result in unexpected and insidious behavior. trace=( 0 UIKitCore 0x0000000195048740 1741FA37-4E53-371E-8DAE-D611AAB0043D + 19457856 1 libdispatch.dylib 0x000000010595a7bc _dispatch_client_callout + 20 2 libdispatch.dylib 0x000000010595c34c _dispatch_once_callout + 140 3 UIKitCore 0x0000000194dcf454 1741FA37-4E53-371E-8DAE-D611AAB0043D + 16864340 4 UIKitCore 0x0000000194dcf37c 1741FA37-4E53-371E-8DAE-D611AAB0043D + 16864124 5 UIKitCore 0x000000019469d40c 1741FA37-4E53-371E-8DAE-D611AAB0043D + 9319436 6 Project 0x0000000104971b70 -[XXXXViewController didFinishChkPrice] + 72 7 ProjectName 0x000000010497b860 -[StoreKitManager finishChkPrice] + 116 8 Application 0x000000010497a70c -[StoreKitManager productsRequest:didReceiveResponse:] + 376 9 StoreKit 0x00000001baecf3b8 F2CA7CCD-9558-3093-AADB-3353C09DD93C + 115640 10 libdispatch.dylib 0x0000000105958b98 _dispatch_call_block_and_release + 32 11 libdispatch.dylib 0x000000010595a7bc _dispatch_client_callout + 20 12 libdispatch.dylib 0x000000010595d30c _dispatch_queue_override_invoke + 1056 13 libdispatch.dylib 0x000000010596eae4 _dispatch_root_queue_drain + 404 14 libdispatch.dylib 0x000000010596f4d8 _dispatch_worker_thread2 + 188 15 libsystem_pthread.dylib 0x00000001eea138f8 _pthread_wqthread + 228 16 libsystem_pthread.dylib 0x00000001eea100cc start_wqthread + 8 ) Unsupported enumeration of UIWindowScene windows on non-main thread. *** Assertion failure in -[UIApplication _performAfterCATransactionCommitsWithLegacyRunloopObserverBasedTiming:block:], UIApplication.m:3246 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Call must be made on main thread' *** First throw call stack: (0x191bbcf20 0x189a42018 0x1910c3868 0x1940b4d28 0x193ff19e8 0x193ff1518 0x194179830 0x1941786e0 0x1941ce440 0x1946a58f0 0x194dc97c0 0x194dcf45c 0x194dcf37c 0x19469d40c 0x104971b70 0x10497b860 0x10497a70c 0x1baecf3b8 0x105958b98 0x10595a7bc 0x10595d30c 0x10596eae4 0x10596f4d8 0x1eea138f8 0x1eea100cc) libc++abi: terminating due to uncaught exception of type NSException

まじでわからん・・・ よくわらないエラーがでるのですが

このエラーの最初に「Main Thread Checker: UI API called on a background thread: -[UIViewController performSegueWithIdentifier:sender:]」 とあります。これは、UI APIがバックグラウンドスレッドで呼ばれていることを示しています。」

・・・?

これも同じ

XXXXViewControllerにある

       [self performSegueWithIdentifier:@"XXXXXView" sender:nil];

   dispatch_async(dispatch_get_main_queue(), ^{
       [self performSegueWithIdentifier:@"XXXXXView" sender:nil];
   });

に修正したらなおった

エラーを調査した結果

performSegueWithIdentifier: メソッドなどのUI操作は、 常にメインスレッドで行うようにするのが推奨されています。iOSのUIはメインスレッドでのみ安全に操作できるため、 他のスレッドからUIを直接操作すると予期しない問題が発生することがあります。

したがって、以下の場合には dispatch_async(dispatch_get_main_queue() を使用してメインスレッドで実行するようにします:

  1. 非同期処理の完了後にUIを更新する場合: バックグラウンドでデータを取得し、その結果をUIに反映させる場合、非同期処理の完了後にメインスレッドでUI操作を行う必要があります。
  2. イベントハンドラ内でUIを更新する場合: ボタンのタップなどのイベントハンドラ内でUI操作を行う場合、その処理もメインスレッドで行う必要があります。
  3. セグエの実行など: performSegueWithIdentifier: やその他のUI遷移を行うメソッドも、メインスレッドで呼び出す必要があります。

通常の場合、UI関連の操作はすべてメインスレッドで 行うようにすることで、アプリの安定性とパフォーマンスを保つことができます。

古いソースはこの画面遷移の部分を修正するのが必須だね

go tourでわからなかったことのメモです

go-tour-jp.appspot.com

package main

import "fmt"

func main() { s := []int{2, 3, 5, 7, 11, 13}

s = s[1:4]
fmt.Println(s)

s = s[:2]
fmt.Println(s)

s = s[1:]
fmt.Println(s)

}

結果は

[3 5 7] [3 5] [5]

でした おお・・・なるほど切り取ってくれて便利だね。と思っていました

試しに改変してみたら想定外の結果になりました

package main

import "fmt"

func main() { s := []int{1,2, 3, 4,5,6,7,8,9,10}

s = s[0:8]
fmt.Println(s)

s = s[:2]
fmt.Println(s)

s = s[:4]
fmt.Println(s)

}

Result

[1 2 3 4 5 6 7 8] [1 2] [1 2 3 4]

最後はエラーになるかな・・・と思っていたら想定外の結果が返ってきたので調べてみた

  1. 最初の s = s[0:8] で、元の s のインデックス0から7までの要素 {1, 2, 3, 4, 5, 6, 7, 8} を持つ新しいスライスが生成され、s がこれに置き換わります。
  2. 次に s = s[:2] で、s はインデックス0から1までの要素 {1, 2} を持つスライスになります。
  3. 最後に s = s[:4] を実行すると、s は現在のスライス {1, 2} の先頭から4つの要素を含むスライスに再定義されます。ただし、元のスライスの要素数を超えてインデックス4までの要素を取ろうとしているため、Go言語では元のスライスの長さに応じて自動的に調整されます。

まじか・・・エラーになった方が楽なんだけど

Objective-Cの初心者の愚痴です。

Objective-C初心者の私が躓いたところです。
とあるプロジェクトをソースだけ引き継ぎをして自分で展開できるのかを確認していました
ソースしかないというアホみたいな状況ですが現実です。
お金をもらっているのでがんばらないといけないのですがマジでObjective-Cプリプロセッサが嫌いです。

IFのネスト(入れ子)ができない

#ifdef USE_POPU_PMENU [self startPopup]; #else #if (APP_TYPE != APP_TYPE_MAP) [self startLaunch]; #else [self performSegueWithIdentifier:@"secondView" sender:nil]; #endif /* (APP_TYPE != APP_TYPE_MAP) / #endif / USE_POPU_PMENU */

クソ言語と呼ばれているvbですらifのネストができます。やり方があるのかもしれないけど見にくいです。 ネストできないところにインデントができるObjective-Cがあるのです。 上の例はまだわかりやすいですがMethodの途中にあるとカオス。

プリプロセッサのDEFINEが嫌い

DEFINEで定義したけど値が入っていないというパターンがあります

#define USE_IMAGE_POST

定義されているけど値が入っていない?? なにか入れてくれよ

さらにややこしいのがプリプロセッサで使えるように ターゲットの単位でもつことができます

例えば、以下のような形でpchがあります

#import "CommonDefine.h"

#ifndef ProjectX_pch #define ProjectX_pch

#ifdef DS #import "CommonDefine_DS.h" #endif #endif /* ProjectX_pch */

この#ifdef DSのDSってどこで設定されているの??
作った人が悪いのですがコメントすら書いていないので?? まじでわからん。しかもDSという短い文字。コメント書いてくれよ!!

色々調べた結果、この値はProjectファイルのターゲットにGCC_PREPROCESSOR_DEFINITIONSがあり そこで設定されています。

GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", DS, );

GUIでは以下です

参考URL

https://qiita.com/edo_m18/items/126fe6561f662b86210e https://www.rk-k.com/archives/6031

前提として

エラー内容

  1. いつもの如く、システムの書類などがなくソースしか残っていない状況だった。
  2. そのアプリの仕組みを使って別のことをできないのかを探ることになった。
  3. ソースを展開して iphone の端末テストを使用したら証明書エラーが発生した
  4. 開発テストで使っている証明書をインストールしたチームの部分がかわらないという現象がおきた
    証明書の部分をGUIで操作してもこのエラーが解消されることはなかった。

対応

1. アプリのプロジェクトファイル(project.pbxproj)をバックアップする.

2. アプリのプロジェクトファイル(project.pbxproj)を vscode で開く.

3. 該当のターゲットの部分を正常にうごいている内容に書き換える

CODE_SIGN_ENTITLEMENTS = XXXXXXXX; CODE_SIGN_IDENTITY = "xxxxxx";

4. Xcodeでプロジェクトをクリーンする

  1. メニューバーから選択: メニューバーから "Product" を選択する
  2. Cleanを選択: "Product" メニューの中から "Clean" を選択する
  3. クリーンの確認: クリーンするかどうか確認される場合があります。確認が表示されたら "Clean" をクリックする

go tourでわからなかったことのメモです

go-tour-jp.appspot.com

package main

import "fmt"

type Vertex struct { X, Y int }

var ( v1 = Vertex{1, 2}
v2 = Vertex{X: 1}
v3 = Vertex{}
p = &Vertex{1, 2} )

func main() { fmt.Println(v1, p, v2, v3) }

なんとなくは理解できたのですがわからないので調べた。

&Vertex{1, 2} の部分について

この部分はGo言語におけるポインタの使用に関するものです。具体的には、&Vertex{1, 2}Vertex 構造体のインスタンスを作成し、そのポインタを返します。

以下に詳細を説明します:

Vertex構造体

まず、Vertex 構造体は以下のように定義されています:

type Vertex struct { X, Y int }

構造体の初期化

Vertex 構造体のインスタンスを作成するには以下のようにします:

v := Vertex{1, 2}

これは、X フィールドに 1Y フィールドに 2 を持つ Vertex 構造体のインスタンスを作成します。

ポインタの取得

ここで、& 演算子を使うことで、Vertex 構造体のインスタンスのポインタを取得できます:

p := &Vertex{1, 2}

このコードは、Vertex 構造体のインスタンスを作成し、そのメモリ上のアドレス(ポインタ)を変数 p に格納します。p の型は *Vertex となります。

ポインタの利用

ポインタを使うことで、構造体のフィールドに対して間接的にアクセスすることができます。例えば:

p := &Vertex{1, 2} fmt.Println(p.X, p.Y)

ここで、p.Xp.Y にアクセスすることで、ポインタを経由して Vertex 構造体のフィールドにアクセスしています。

プログラムの動作

質問にあるプログラムの main 関数では、以下のようにしています:

func main() { fmt.Println(v1, v2, v3) fmt.Println(p) }

このプログラムを実行すると、構造体インスタンスの内容とポインタが表示されます:

{1 2} {1 0} {0 0} &{1 2}

最初の Println では v1, v2, v3 の値が表示され、次の Println ではポインタ p が指す Vertex 構造体の内容が表示されます(ポインタであることを示す & が付いています)。

間接的に操作する例

以下の例では、Vertex 構造体のフィールドをポインタを通じて変更する方法を示しています。

package main

import "fmt"

type Vertex struct { X, Y int }

func updateVertex(v *Vertex, newX int, newY int) { v.X = newX v.Y = newY }

func main() {

p := &Vertex{1, 2}


fmt.Println("Before update:", *p)


updateVertex(p, 10, 20)


fmt.Println("After update:", *p)

}

このプログラムの出力は以下のようになります:

Before update: {1 2} After update: {10 20}

説明

  1. 構造体のポインタを作成:go p := &Vertex{1, 2} これは、X1Y2 である Vertex 構造体のポインタを作成します。
  2. 初期値を表示:go fmt.Println("Before update:", *p) *p を使うことでポインタ p が指す構造体の値を取得し、初期値 {1 2} が表示されます。
  3. 関数 updateVertex でフィールドを更新:go updateVertex(p, 10, 20) この関数は、ポインタ p を受け取り、X フィールドを 10 に、Y フィールドを 20 に更新します。
  4. 更新後の値を表示:go fmt.Println("After update:", *p) 再び *p を使って更新後の構造体の値を表示します。この時点で、X10Y20 になっています。

このように、ポインタを使うことで構造体のフィールドを間接的に操作できます。 ポインタを関数に渡すことで、関数内で構造体の内容を変更できる点が重要です。