ChatGPTにいろいろな呪文を唱えて、魔法を詠唱してもらった for Python.

# ChatGPTでいろいろなパターンのコードを書いてもらう for Python.
タイトル通りです。ChatGPTにいろいろな呪文を唱えて(指示を与えて)、魔法を詠唱(コード生成)してもらった。
なお、本記事の構成は、「呪文>魔法詠唱(サンプルコード)>補足説明」となっています。

## 簡単なスクレイピング 1
まずは、ありきたりなスクレイピングに関する魔法を詠唱(コード)してもらった。
簡単な魔法がどれくらいなのか？精度も知りたく、以下の内容で呪文をかけてみた。

はじめの呪文(指示)は次の通りです。
```:呪文
pythonコードで、特定のサイトをスクレイピングして、
テーブルタグのデータをexcelに落とし込み、各データのテーブルを作成するコード書いて
```
魔法詠唱
```Python3:魔法詠唱
import requests
from bs4 import BeautifulSoup
import pandas as pd

# スクレイピング対象のURL
url = "https://example.com"

# requestsを使用してHTMLを取得
res = requests.get(url)
soup = BeautifulSoup(res.text, 'html.parser')

# テーブルタグを抽出
table = soup.find('table')

# テーブルから行を抽出
rows = table.find_all('tr')

# 各行からセルを抽出し、二次元配列に格納
data = [[cell.text for cell in row.find_all(['th', 'td'])] for row in rows]

# pandasのDataFrameに変換
df = pd.DataFrame(data)

# Excelに書き込み
df.to_excel('table_data.xlsx', index=False, header=False)
```

### 補足説明
```
Pythonを使用してWebスクレイピングを行うためには、「BeautifulSoup」というライブラリを使用することが一般的です。
これにより、HTMLやXMLからデータを取得するための豊富なメソッドが利用できます。
また、Excelにデータを書き込むためには「pandas」ライブラリを使用することができます。

以下は、特定のサイトからテーブルタグのデータをスクレイピングし、Excelに書き込むためのサンプルコードです。

注意点: スクレイピングには相手先の許可が必要です。
また、スクレイピングをする際には、相手先のページの変更に対応できるように、定期的にスクレイピングを行うようにしてください
```

## スクレイピング 2
さらにより指示を細かくして、詠唱してもらった。
また、言い回しなどの部分で、少し日本語をおかしくしてみました。
```:呪文
このコードで、url:https://example.com/search/のページで、
クラス「option_area」に子にあるテーブル要素をExcelにテーブルデータ化するコードに変えてください。
```
魔法詠唱
```Python3:魔法詠唱
import requests
from bs4 import BeautifulSoup
import pandas as pd

# スクレイピング対象のURL
url = "https://example.com/search/"

# requestsを使用してHTMLを取得
res = requests.get(url)
soup = BeautifulSoup(res.text, 'html.parser')

# option_areaクラスからテーブルを抽出
table = soup.find('div', {'class': 'option_area'}).find('table')

# テーブルから行を抽出
rows = table.find_all('tr')

# 各行からセルを抽出し、二次元配列に格納
data = [[cell.text for cell in row.find_all(['th', 'td'])] for row in rows]

# pandasのDataFrameに変換
df = pd.DataFrame(data)

# Excelに書き込み
df.to_excel('table_data.xlsx', index=False, header=False)
```

### 補足説明
```
以下は、https://example.com/search/ ページから、
クラス「option_area」に子にあるテーブル要素をスクレイピングし、Excelにテーブルデータ化するためのサンプルコードです。

このコードでは、「find」メソッドを使用して、
class属性が「option_area」のdiv要素から、テーブルタグを抽出しています。
また、そのテーブルタグから、各行を抽出し、それぞれのセルを取得し、二次元配列に格納しています。
最後に、PandasのDataFrameに変換し、Excelに書き込んでいます。

このコードは一例であり、実際には、サイトの構造や、取得したいデータによっては、修正が必要になる場合があります。
```
スクレイピング実行の結果...ほぼ完ぺきな状態に仕上がりで、呪文に対する魔法もかなりいい精度でした。
これくらいなら、自分で書いても大したものじゃないので、すぐかけちゃいますが...
スクレイピング初心者の駆け出しにしてはいい感じではないでしょうか。
また日本語をおかしくしてみて、人間なら解釈してくれる程度にしてみた結果も言い回しに関係なく、
指摘や言い換えなどもなしにちゃんと魔法詠唱してくれるというやさしさに感動しました。


## ネットワークに関する内容で、呪文を唱えてみた
では続いて、少しコアな呪文を唱えてみました。

人間は、忙しい時ほど、厄災が降りかかるものだ。
ということで、くっそ面倒な依頼を与えられたので、
AIの力を借りて真の価値を見せてもらいました。
要件は、ネットワーク上に存在するIPを調べるために、
サブネットマスクを調べるようの魔法を詠唱してもらいました。

なお、真価については、人によりけりかと思います。
まぁ、結果を先に伝えますと自分にとっては最高によかったです。
ゼロから書く手間を考慮したらその間に別の作業ができたのでｗ

では、呪文を唱えてみましょう。
```:呪文
pythonコードで、ip サブネットマスクをそれぞれ計算して出力するコード書いて下さい。
```
魔法詠唱
```Python3:魔法詠唱
import ipaddress

# IPアドレスとサブネットマスク
ip = "192.168.1.1"
mask = "255.255.255.0"

# IPアドレスとサブネットマスクをipaddressオブジェクトに変換
ip_obj = ipaddress.ip_address(ip)
mask_obj = ipaddress.ip_address(mask)

# IPアドレスとサブネットマスクを使用して、それぞれのサブネットを計算
network = ip_obj & mask_obj
broadcast = ip_obj | ~mask_obj

# 出力
print("Network: ", network)
print("Broadcast: ", broadcast)
```

### 補足説明
```
IPアドレスとサブネットマスクを使用して、それぞれのサブネットを計算するためには、
「ipaddress」というライブラリを使用することができます。
これにより、IPアドレスやサブネットマスクの操作を簡単に行うことができます。

以下は、IPアドレス「192.168.1.1」とサブネットマスク「255.255.255.0」を使用して、
それぞれのサブネットを計算し、出力するサンプルコードです。
このコードでは、IPアドレスやサブネットマスクを文字列として取得し、
それぞれをipaddressオブジェクトに変換しています。
その後、「&」演算子を使用して、ネットワークアドレスを計算し、「|」演算子を使用して、
ブロードキャストアドレスを計算し、それぞれを出力しています。

このコードは一例であり、実際には、IPアドレスやサブネットマスクが異なる場合は、適切に調整する必要があります。
```


### 
```:呪文
上記のコードを実行すると
「TypeError: unsupported operand type(s) for &: 'IPv4Address' and 'IPv4Address'」
というエラーになるけど、何が原因ですか？
```
### 補足説明
```
上記のコードで発生している
「TypeError: unsupported operand type(s) for &: 'IPv4Address' and 'IPv4Address'」というエラーは、
「ipaddress」ライブラリで定義されている「ip_address」オブジェクトに対して、ビット演算子を使用しているために発生しています。

IPアドレスやサブネットマスクを計算するには、
「ipaddress」ライブラリで定義されている「ip_network」オブジェクトを使用する必要があります。
「ip_network」オブジェクトは、IPアドレスとサブネットマスクを組み合わせた情報を保持し、
サブネット計算に必要な情報を持っています。

次のように変更して、IPアドレスやサブネットマスクを「ip_network」オブジェクトに変換して、サブネット計算を行うことができます。
```

魔法詠唱
```Python3:魔法詠唱
# IPアドレスとサブネットマスク
ip_network = "192.168.1.1/24"

# IPアドレスとサブネットマスクをipaddressオブジェクトに変換
ip_network_obj = ipaddress.ip_network(ip_network)

# 出力
print("Network: ", ip_network_obj.network_address)
print("Broadcast: ", ip_network_obj.broadcast_address)
```

```:呪文
このコードでは、
「ValueError: 192.168.1.1/24 has host bits set」エラーとなるため、
以下のコードに直した方がいいのでは？
```
```Python3:指摘したコード
# IPアドレスとサブネットマスク
ip_network = "192.168.1.0/24"

# IPアドレスとサブネットマスクをipaddressオブジェクトに変換
ip_network_obj = ipaddress.ip_network(ip_network)

# 出力
print("Network: ", ip_network_obj.network_address)
print("Broadcast: ", ip_network_obj.broadcast_address)
```

### 返信内容
```
その通りです。
「ValueError: 192.168.1.1/24 has host bits set」というエラーは、
IPアドレスにホスト部分が設定されているために発生します。

IPアドレスには、ネットワークアドレスとホストアドレスの二つの部分があります。
ネットワークアドレスは、サブネット計算に使用され、ホストアドレスは、特定のデバイスを識別するために使用されます。

サブネット計算を行う場合は、IPアドレスのネットワーク部分を使用する必要があります。
そのため、上記のコードでは、「192.168.1.0/24」のように、
IPアドレスのネットワーク部分を使用して、サブネット計算を行っています。

それによって、正しいサブネットアドレスが出力されることが保証されます。
```

結果、指摘しても間違いを認め、補足説明でカバーしてくれるという仕様。
気を遣わずに、突っ込めるってめっちゃいいパートナー。
頼りすぎもあまりよくないってこともこれで分かった。

## おまけの魔法詠唱
最後に、ネットワークで特定のIPを調べるためのコードが次のものとなります。
このコードは、指定したIPに対して、指定されたポートが開放されているかを確認するためのコードになります。
使うのに注意してご使用ください。nmapの劣化版みたいなやつですｗ

ちなみに、わたくしは、自社システムのメンテ用に利用しており、
閉域網内のネットワーク上で利用しています。
このような簡易ツールみたいなコードは、よく使うので、謎コードがいっぱいありますｗ

魔法詠唱
```Python3:network_scan.py
import socket, ipaddress

class port_scanning:
    def __init__(self, host, scan_port, delay, ptl_name):
        self.status  = False
        self.remoteServer, self.port, self.delay, self.ptl_name, self.sevice_name, self.result = host, int(scan_port), delay, ptl_name, "", {"status": self.status}
        self.remoteServerIP  = socket.gethostbyname(self.remoteServer)
    def run(self):
        try:
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM)as sock:
                self.sevice_name = socket.getservbyport(int(self.port), self.ptl_name)
                sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                sock.settimeout(self.delay)
                self.status  = ("NG", "OK")[sock.connect_ex((self.remoteServerIP, int(self.port))) == 0]
                self.result  = {"status": f"{self.status}", "sevice_name":f"{self.sevice_name}", "protocol_name":f"{self.ptl_name}", "remote_server": f"{self.remoteServer}", "port": f"{self.port}"}
                if self.result:
                    sock.shutdown(socket.SHUT_RDWR)
                    sock.detach()
                else:
                    sock.detach()
        except:
            self.result.update({"error_msg[port_scanning]":f'{sys.exc_info()[0]}, {sys.exc_info()[1]}'})
        return self.result

    def __enter__(self):
        return self

    def __exit__(self, exception_type, exception_value, traceback):
        return True

if __name__ == '__main__':
    # IPアドレスとprefixlen
    ip_network = "192.168.0.0/24"

    # IPアドレスとサブネットマスクをipaddressオブジェクトに変換
    ip_network_obj = ipaddress.ip_network(ip_network)

    # 出力
    print("Network: ", ip_network_obj.network_address)
    print("Broadcast: ", ip_network_obj.broadcast_address)
    print(f'Netmask: {ip_network_obj.netmask}')

    for ip in ip_network_obj.hosts():
        host_ip, scan_port, delay, ptl_name = f'{ip}', 80, 1, 'tcp'
        with port_scanning(host_ip, scan_port, delay, ptl_name) as sc:
                print(sc.run())
```

以上、お粗末なコード集でした。
今後、数か月後先にはこのサービスでは、
このような呪文の宝庫になってそうな予感しかしないｗ