GPT-4 で コードを書いてもらったら最後は Python がカッコ良くなった

### 概要
2023年3月25時点の話。
GPT-4に要件を伝えて Phthon のコードを作成してもらいました。
そののち Go, C, Node.js, Java, Rust, C#, Delphi でも作成してもらい、
そしてもういちど Phthon で作成してもらったところ最初のPythonのコードよりもカッコ良くなっていました。
最後に GPT-4 に注文をつけて再度 Python のコードを修正してもらいました。

もしかして１週間後にやってみるとまた違った結果を出力するかもしれないので3月25時点で経緯をそのまま記録しておきます。


### 要件定義
```
青空文庫から夏目漱石の「吾輩は猫である」の圧縮ファイルを取得して
ローカルPCの D:\aozora にテキストファイルとして格納するプログラムを
○○言語 で作成してコードを示して下さい。
```

### Python １回目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/785c769f-4a92-6bff-48bb-2e5c0576b0a8.png)

```
import os
import zipfile
import requests

# 夏目漱石の「吾輩は猫である」の圧縮ファイルのURL
url = "https://www.aozora.gr.jp/cards/000148/files/789_ruby_5639.zip"

# ダウンロード先のファイル名
download_file = "wagahaiwa_nekodearu.zip"

# ダウンロードして保存
response = requests.get(url)
with open(download_file, "wb") as f:
    f.write(response.content)

# ローカルPCの保存先フォルダ
output_folder = "D:\\aozora"

# 保存先フォルダが存在しない場合、作成
if not os.path.exists(output_folder):
    os.makedirs(output_folder)

# 圧縮ファイルの解凍
with zipfile.ZipFile(download_file, "r") as z:
    z.extractall(output_folder)

# ダウンロードした圧縮ファイルを削除
os.remove(download_file)

print("ダウンロードと解凍が完了しました。")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/14005421-3cfe-b20b-944b-c60a10dc855e.png)

### Go

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/f8357672-ff4c-24d7-568f-6296a938b74d.png)

```
package main

import (
	"archive/zip"
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"
)

func main() {
	// 夏目漱石の「吾輩は猫である」の圧縮ファイルのURL
	url := "https://www.aozora.gr.jp/cards/000148/files/789_ruby_5639.zip"
	
	// ダウンロード先のファイル名
	downloadFile := "wagahaiwa_nekodearu.zip"

	// ダウンロードして保存
	response, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer response.Body.Close()

	out, err := os.Create(downloadFile)
	if err != nil {
		panic(err)
	}
	defer out.Close()

	_, err = io.Copy(out, response.Body)
	if err != nil {
		panic(err)
	}

	// ローカルPCの保存先フォルダ
	outputFolder := "D:\\aozora"

	// 保存先フォルダが存在しない場合、作成
	if _, err := os.Stat(outputFolder); os.IsNotExist(err) {
		os.MkdirAll(outputFolder, os.ModePerm)
	}

	// 圧縮ファイルの解凍
	z, err := zip.OpenReader(downloadFile)
	if err != nil {
		panic(err)
	}
	defer z.Close()

	for _, f := range z.File {
		dstPath := filepath.Join(outputFolder, f.Name)
		dstFile, err := os.Create(dstPath)
		if err != nil {
			panic(err)
		}
		defer dstFile.Close()

		srcFile, err := f.Open()
		if err != nil {
			panic(err)
		}

		_, err = io.Copy(dstFile, srcFile)
		if err != nil {
			panic(err)
		}

		srcFile.Close()
	}

	// ダウンロードした圧縮ファイルを削除
	os.Remove(downloadFile)

	fmt.Println("ダウンロードと解凍が完了しました。")
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/5a69b72c-eec0-8084-dedb-6478d5c841df.png)

### C

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/c67e1844-2bc0-f65c-f235-8a051c5ef165.png)

```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <curl/curl.h>
#include <minizip/unzip.h>

size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    FILE *fp = (FILE *) userp;
    fwrite(contents, size, nmemb, fp);
    return realsize;
}

int download_file(const char *url, const char *filename) {
    CURL *curl;
    CURLcode res;
    FILE *fp;

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();

    if (!curl) {
        fprintf(stderr, "curl_easy_init() failed\n");
        return 1;
    }

    fp = fopen(filename, "wb");
    if (!fp) {
        perror("fopen");
        return 1;
    }

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

    res = curl_easy_perform(curl);

    if (res != CURLE_OK) {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
    }

    fclose(fp);
    curl_easy_cleanup(curl);
    curl_global_cleanup();

    return 0;
}

int extract_zip(const char *zip_filename, const char *destination) {
    char buf[1024];
    unzFile uf = unzOpen(zip_filename);
    if (!uf) {
        fprintf(stderr, "unzOpen failed\n");
        return 1;
    }

    if (unzGoToFirstFile(uf) != UNZ_OK) {
        fprintf(stderr, "unzGoToFirstFile failed\n");
        unzClose(uf);
        return 1;
    }

    do {
        if (unzOpenCurrentFile(uf) != UNZ_OK) {
            fprintf(stderr, "unzOpenCurrentFile failed\n");
            unzClose(uf);
            return 1;
        }

        unz_file_info64 info;
        char filename[256];
        unzGetCurrentFileInfo64(uf, &info, filename, sizeof(filename), NULL, 0, NULL, 0);

        char outpath[512];
        snprintf(outpath, sizeof(outpath), "%s/%s", destination, filename);

        FILE *out = fopen(outpath, "wb");
        if (!out) {
            perror("fopen");
            unzCloseCurrentFile(uf);
            unzClose(uf);
            return 1;
        }

        int err
        do {
            err = unzReadCurrentFile(uf, buf, sizeof(buf));
            if (err < 0) {
                fprintf(stderr, "unzReadCurrentFile failed: %d\n", err);
                unzCloseCurrentFile(uf);
                unzClose(uf);
                fclose(out);
                return 1;
            }
            fwrite(buf, 1, err, out);
        } while (err > 0);

        fclose(out);
        unzCloseCurrentFile(uf);

    } while (unzGoToNextFile(uf) == UNZ_OK);

    unzClose(uf);
    return 0;
}

int main() {
    const char *url = "https://www.aozora.gr.jp/cards/000148/files/789_ruby_5639.zip";
    const char *download_file = "wagahaiwa_nekodearu.zip";
    const char *output_folder = "D:\\aozora";

    if (download_file(url, download_file) != 0) {
        fprintf(stderr, "Failed to download file\n");
        return 1;
    }

    if (access(output_folder, F_OK) == -1) {
        if (mkdir(output_folder, 0777) == -1) {
            perror("mkdir");
            return 1;
        }
    }

    if (extract_zip(download_file, output_folder) != 0) {
        fprintf(stderr, "Failed to extract ZIP file\n");
        return 1;
    }

    if (remove(download_file) != 0) {
        perror("remove");
        return 1;
    }

    printf("ダウンロードと解凍が完了しました。\n");

    return 0;
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/d89120a9-efdb-79cf-6eea-775790a4dff7.png)

### Node.js
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/3cb2feb3-cd18-a635-888f-bebc52bd5172.png)

```
npm install node-fetch extract-zip
```

```
const fs = require('fs');
const fetch = require('node-fetch');
const extract = require('extract-zip');

const url = 'https://www.aozora.gr.jp/cards/000148/files/789_ruby_5639.zip';
const downloadFile = 'wagahaiwa_nekodearu.zip';
const outputFolder = 'D:\\aozora';

async function downloadAndSave(url, filePath) {
  const response = await fetch(url);
  const buffer = await response.buffer();
  fs.writeFileSync(filePath, buffer);
}

async function extractZip(zipPath, outputPath) {
  try {
    await extract(zipPath, { dir: outputPath });
  } catch (err) {
    console.error('Error extracting zip file:', err);
  }
}

(async () => {
  try {
    await downloadAndSave(url, downloadFile);
    if (!fs.existsSync(outputFolder)) {
      fs.mkdirSync(outputFolder, { recursive: true });
    }
    await extractZip(downloadFile, outputFolder);
    fs.unlinkSync(downloadFile);
    console.log('ダウンロードと解凍が完了しました。');
  } catch (err) {
    console.error('Error:', err);
  }
})();
```

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/e2c0a62c-4918-834e-3c5e-3db3d2f66d06.png)

### Java
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/26791462-a4a8-dea2-6822-a8bd38bcbd26.png)

import java.io.*;
import java.net.URL;
import java.nio.file.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class AozoraDownloader {
    public static void main(String[] args) {
        String url = "https://www.aozora.gr.jp/cards/000148/files/789_ruby_5639.zip";
        String downloadFile = "wagahaiwa_nekodearu.zip";
        String outputFolder = "D:\\aozora";

        try {
            downloadAndSave(url, downloadFile);
            extractZip(downloadFile, outputFolder);
            Files.delete(Paths.get(downloadFile));

            System.out.println("ダウンロードと解凍が完了しました。");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void downloadAndSave(String url, String filePath) throws IOException {
        try (InputStream in = new URL(url).openStream()) {
            Files.copy(in, Paths.get(filePath), StandardCopyOption.REPLACE_EXISTING);
        }
    }

    private static void extractZip(String zipFilePath, String destDir) throws IOException {
        File dir = new File(destDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath))) {
            ZipEntry entry = zipIn.getNextEntry();
            while (entry != null) {
                String filePath = destDir + File.separator + entry.getName();
                if (!entry.isDirectory()) {
                    extractFile(zipIn, filePath);
                } else {
                    File subDir = new File(filePath);
                    subDir.mkdirs();
                }
                zipIn.closeEntry();
                entry = zipIn.getNextEntry();
            }
        }
    }

    private static void extractFile(ZipInputStream zipIn, String filePath) throws IOException {
        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath))) {
            byte[] bytesIn = new byte[4096];
            int read;
            while ((read = zipIn.read(bytesIn)) != -1) {
                bos.write(bytesIn, 0, read);
            }
        }
    }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/eb158a99-1901-42fe-8bb7-15634046ffaf.png)

### Rust
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/583eb667-6f18-3159-3026-246022d467bf.png)

```
[dependencies]
reqwest = { version = "0.11", features = ["blocking", "json"] }
zip = "0.5"
tokio = { version = "1", features = ["full"] }
```

```
use std::fs::{self, File};
use std::io::{BufWriter, Read};
use std::path::Path;
use zip::read::ZipArchive;

fn main() {
    let url = "https://www.aozora.gr.jp/cards/000148/files/789_ruby_5639.zip";
    let download_file = "wagahaiwa_nekodearu.zip";
    let output_folder = "D:\\aozora";

    if let Err(e) = download_and_save(url, download_file) {
        eprintln!("Failed to download file: {}", e);
        return;
    }

    if let Err(e) = extract_zip(download_file, output_folder) {
        eprintln!("Failed to extract ZIP file: {}", e);
        return;
    }

    if let Err(e) = fs::remove_file(download_file) {
        eprintln!("Failed to remove downloaded file: {}", e);
        return;
    }

    println!("ダウンロードと解凍が完了しました。");
}

fn download_and_save(url: &str, file_path: &str) -> Result<(), Box<dyn std::error::Error>> {
    let response = reqwest::blocking::get(url)?;
    let bytes = response.bytes()?;
    let mut file = File::create(file_path)?;
    file.write_all(&bytes)?;
    Ok(())
}

fn extract_zip(zip_file_path: &str, output_folder: &str) -> Result<(), Box<dyn std::error::Error>> {
    let file = File::open(zip_file_path)?;
    let mut archive = ZipArchive::new(file)?;

    for i in 0..archive.len() {
        let mut file = archive.by_index(i)?;
        let outpath = Path::new(output_folder).join(file.name());

        if file.is_dir() {
            fs::create_dir_all(&outpath)?;
        } else {
            if let Some(p) = outpath.parent() {
                if !p.exists() {
                    fs::create_dir_all(&p)?;
                }
            }
            let mut outfile = BufWriter::new(File::create(&outpath)?);
            std::io::copy(&mut file, &mut outfile)?;
        }
    }

    Ok(())
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/0f1434df-7105-f784-36cc-5131cb00ad2b.png)

### C#
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/17607add-fd2e-0cb1-9b92-eb6ddec0ac37.png)

```
using System;
using System.IO;
using System.IO.Compression;
using System.Net.Http;
using System.Threading.Tasks;

namespace AozoraDownloader
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string url = "https://www.aozora.gr.jp/cards/000148/files/789_ruby_5639.zip";
            string downloadFile = "wagahaiwa_nekodearu.zip";
            string outputFolder = "D:\\aozora";

            try
            {
                await DownloadAndSave(url, downloadFile);
                ExtractZip(downloadFile, outputFolder);
                File.Delete(downloadFile);

                Console.WriteLine("ダウンロードと解凍が完了しました。");
            }
            catch (Exception e)
            {
                Console.Error.WriteLine($"Error: {e.Message}");
            }
        }

        private static async Task DownloadAndSave(string url, string filePath)
        {
            using var httpClient = new HttpClient();
            using var response = await httpClient.GetAsync(url);
            response.EnsureSuccessStatusCode();

            using var fileStream = File.Create(filePath);
            await response.Content.CopyToAsync(fileStream);
        }

        private static void ExtractZip(string zipFilePath, string destDir)
        {
            if (!Directory.Exists(destDir))
            {
                Directory.CreateDirectory(destDir);
            }

            using var archive = ZipFile.OpenRead(zipFilePath);
            foreach (var entry in archive.Entries)
            {
                string entryPath = Path.Combine(destDir, entry.FullName);
                if (entry.Length == 0)
                {
                    Directory.CreateDirectory(entryPath);
                }
                else
                {
                    entry.ExtractToFile(entryPath, overwrite: true);
                }
            }
        }
    }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/bb4a9e51-fc82-0b06-5d38-fb34258d277a.png)

### Delphi
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/1b931653-ba0d-7e8f-07e0-0bbcbdb580a1.png)

```
program AozoraDownloader;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Net.HttpClient,
  System.Net.URLClient,
  System.IOUtils,
  System.Zip;

const
  Url = 'https://www.aozora.gr.jp/cards/000148/files/789_ruby_5639.zip';
  DownloadFile = 'wagahaiwa_nekodearu.zip';
  OutputFolder = 'D:\aozora';

procedure DownloadAndSave(const AUrl, AFilePath: string);
var
  LHttpClient: THTTPClient;
  LResponse: IHTTPResponse;
begin
  LHttpClient := THTTPClient.Create;
  try
    LResponse := LHttpClient.Get(AUrl);
    if LResponse.StatusCode = 200 then
      TFile.WriteAllBytes(AFilePath, LResponse.ContentAsBytes);
  finally
    LHttpClient.Free;
  end;
end;

procedure ExtractZip(const AZipFilePath, ADestDir: string);
var
  LZipFile: TZipFile;
begin
  LZipFile := TZipFile.Create;
  try
    LZipFile.Open(AZipFilePath, TZipMode.zmRead);
    LZipFile.ExtractAll(ADestDir);
  finally
    LZipFile.Free;
  end;
end;

begin
  try
    DownloadAndSave(Url, DownloadFile);
    if not TDirectory.Exists(OutputFolder) then
      TDirectory.CreateDirectory(OutputFolder);
    ExtractZip(DownloadFile, OutputFolder);
    TFile.Delete(DownloadFile);

    WriteLn('ダウンロードと解凍が完了しました。');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/06111e26-3b61-0c07-edbd-b41d725752aa.png)


### Phthon ２回目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/598d74cb-85c9-bdbc-6481-31f9c6423faf.png)

```
import os
import requests
import zipfile

url = "https://www.aozora.gr.jp/cards/000148/files/789_ruby_5639.zip"
download_file = "wagahaiwa_nekodearu.zip"
output_folder = "D:\\aozora"

def download_and_save(url, file_path):
    response = requests.get(url)
    with open(file_path, "wb") as file:
        file.write(response.content)

def extract_zip(zip_file_path, dest_dir):
    with zipfile.ZipFile(zip_file_path, "r") as zip_file:
        zip_file.extractall(dest_dir)

try:
    download_and_save(url, download_file)
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    extract_zip(download_file, output_folder)
    os.remove(download_file)

    print("ダウンロードと解凍が完了しました。")
except Exception as e:
    print(f"Error: {e}")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/3c453d32-3713-8a98-60c3-d2a2dae15b19.png)

### Phthon ３回目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/5915c063-fd4a-ded0-d185-409cb4eb12f6.png)

```
import os
import requests
import zipfile

def download_and_save(url, file_path):
    response = requests.get(url)
    with open(file_path, "wb") as file:
        file.write(response.content)

def extract_zip(zip_file_path, dest_dir):
    with zipfile.ZipFile(zip_file_path, "r") as zip_file:
        zip_file.extractall(dest_dir)

def main():
    url = "https://www.aozora.gr.jp/cards/000148/files/789_ruby_5639.zip"
    download_file = "wagahaiwa_nekodearu.zip"
    output_folder = "D:\\aozora"

    try:
        download_and_save(url, download_file)
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)
        extract_zip(download_file, output_folder)
        os.remove(download_file)

        print("ダウンロードと解凍が完了しました。")
    except Exception as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    main()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/b3721c4f-7e23-4761-85ef-48d642e058d2.png)