AI 지원 코딩 분야에서 OpenAI ChatGPT 5Grok 4는 2025년 가장 주목받는 두 가지 도구입니다. 두 도구 모두 높은 정확도와 효율성으로 Python 코드를 작성한다고 주장하지만, 실제 환경에서는 어느 쪽이 더 깔끔하고 유지 관리가 용이한 스크립트를 제공할까요?

이 글에서는 ChatGPT 5Grok 4를 여러 Python 과제에서 서로 비교해 보겠습니다. 코드 정확성, 가독성, 실행 속도, 그리고 까다로운 상황에서의 적응성을 검토합니다.

Python에서 ChatGPT 5와 Grok 4를 비교해야 하는 이유는 무엇일까요?

Python은 여전히 AI, 자동화, 데이터 과학 분야의 주요 언어로 자리 잡고 있습니다. 많은 개발자들이 코딩 워크플로우를 가속화하고, 디버깅 속도를 높이고, 심지어 처음부터 완전한 애플리케이션을 생성하기 위해 AI를 활용하고 있습니다.

ChatGPT가 오랫동안 이 분야를 장악해 왔지만, Grok은 코드 명확성간결한 출력으로 주목을 받고 있습니다. 두 회사 모두 서로 다른 교육 철학을 사용합니다. ChatGPT는 추론에 중점을 두는 반면, Grok은 간결함에 중점을 둡니다.

OpenAI ChatGPT 5와 Grok 4 테스트

10가지 Python 코딩 테스트 사례를 통해 두 AI를 비교해 보겠습니다.

  1. 기본 스크립트 (짝수 합)
  2. 데이터 처리 (CSV 합계)
  3. 알고리즘 문제 (첫 번째 반복되지 않는 문자)
  4. API 통합 (비트코인 가격 가져오기)
  5. 웹 스크래핑 (해커 뉴스 헤드라인)
  6. 파일 압축 (.txt 파일 압축)
  7. 이미지 처리 (JPEG 크기 조정)
  8. 멀티스레딩 (동시 다운로드)
  9. 데이터베이스 상호작용 (SQLite CRUD)
  10. 단위 테스트 (소수 테스트)

모든 프롬프트는 동일하며 ChatGPT 5Grok 4에 제출됩니다. 직접 테스트를 실행하여 결과를 검증할 수 있습니다.

Python 챌린지 1 - 기본 스크립트

챌린지 1 프롬프트:

정수 목록을 읽고 짝수의 합을 출력하는 Python 스크립트를 작성하세요.

챌린지 1 GPT 5 코드:

 1# Script to read a list of integers and output the sum of even numbers
 2def sum_of_even_numbers(numbers):
 3    return sum(num for num in numbers if num % 2 == 0)
 4
 5if __name__ == "__main__":
 6    # Read input from the user
 7    try:
 8        numbers = list(map(int, input("Enter integers separated by spaces: ").split()))
 9        total_even = sum_of_even_numbers(numbers)
10        print("Sum of even numbers:", total_even)
11    except ValueError:
12        print("Please enter valid integers only.")

챌린지 1 Grok 4 코드:

 1# Read a line of input containing space-separated integers
 2input_line = input("Enter a list of integers separated by spaces: ")
 3
 4# Convert the input string into a list of integers
 5numbers = list(map(int, input_line.split()))
 6
 7# Initialize sum of even numbers
 8even_sum = 0
 9
10# Iterate through the list and add even numbers to the sum
11for num in numbers:
12    if num % 2 == 0:
13        even_sum += num
14
15# Output the sum
16print("Sum of even numbers:", even_sum)

챌린지 1 관찰 결과:

  • GPT 5 속도: 매우 빠른 응답, 거의 즉각적입니다.
  • GPT 5 코드: 진입점과 주석이 있는 더 짧고 세련된 코드를 제공했습니다.
  • Grok 4 속도: 응답 속도가 느리고, “생각"하는 데 약간 더 오래 걸렸습니다(약 2초).
  • Grok 4 코드: 진입점은 없지만 주석이 있는 약간 더 긴 코드를 제공했습니다.

Python 챌린지 2 - 데이터 처리

챌린지 2 프롬프트:

거래 내역이 담긴 CSV 파일을 로드하고 제품별 총 매출을 출력합니다.

챌린지 2 GPT 5 코드:

 1import csv
 2from collections import defaultdict
 3
 4def total_sales_per_product(csv_file):
 5    sales = defaultdict(float)
 6
 7    with open(csv_file, newline='', encoding='utf-8') as f:
 8        reader = csv.DictReader(f)
 9        for row in reader:
10            try:
11                product = row['product']
12                quantity = float(row['quantity'])
13                price = float(row['price'])
14                sales[product] += quantity * price
15            except (KeyError, ValueError):
16                print(f"Skipping invalid row: {row}")
17
18    return sales
19
20if __name__ == "__main__":
21    file_path = "transactions.csv"  # Change to your file path
22    sales_totals = total_sales_per_product(file_path)
23
24    print("Total Sales Per Product:")
25    for product, total in sales_totals.items():
26        print(f"{product}: ${total:,.2f}")

챌린지 2 Grok 4 코드:

 1import pandas as pd
 2
 3# Prompt user for the CSV file path
 4file_path = input("Enter the path to the CSV file: ")
 5
 6# Load the CSV file into a DataFrame
 7df = pd.read_csv(file_path)
 8
 9# Assuming the CSV has columns 'Product' and 'Sales'
10# Group by 'Product' and sum the 'Sales'
11total_sales = df.groupby('Product')['Sales'].sum()
12
13# Print the total sales per product
14print("Total sales per product:")
15print(total_sales)

챌린지 2 관찰 결과:

  • GPT 5 속도: 매우 빠른 응답, 거의 즉각적입니다.
  • GPT 5 코드: 진입점은 있지만 주석은 없는 좀 더 길고 세련된 코드를 제공했습니다.
  • Grok 4 속도: 응답 속도가 느리고, “생각"하는 데 시간이 좀 더 걸렸습니다(약 13초).
  • Grok 4 코드: 진입점은 없지만 주석은 있는 좀 더 간단한 코드를 제공했습니다.

Python 챌린지 3 - 알고리즘 문제

챌린지 3 프롬프트:

문자열이 주어졌을 때, 반복되지 않는 첫 번째 문자를 반환합니다.

챌린지 3 GPT 5 코드:

 1def first_non_repeating_char(s):
 2    from collections import Counter
 3    counts = Counter(s)
 4
 5    for char in s:
 6        if counts[char] == 1:
 7            return char
 8    return None  # If no non-repeating character found
 9
10# Example usage
11text = "swiss"
12result = first_non_repeating_char(text)
13if Code:
14    print(f"The first non-repeating character is: '{result}'")
15else:
16    print("No non-repeating character found.")

챌린지 3 Grok 4 코드:

 1import collections
 2
 3def first_non_repeating_char(s):
 4    """
 5    Returns the first non-repeating character in the string.
 6    If no such character exists, returns None.
 7    """
 8    count = collections.Counter(s)
 9    for char in s:
10        if count[char] == 1:
11            return char
12    return None
13
14# Example usage
15input_string = input("Enter a string: ")
16result = first_non_repeating_char(input_string)
17print("First non-repeating character:", result)

챌린지 3 관찰 결과:

  • GPT 5 속도: 매우 빠른 응답, 거의 즉각적입니다.
  • GPT 5 코드: 진입점과 주석 없이 짧은 코드를 제공했습니다. 예시 사용에 버그가 있습니다.
  • Grok 4 속도: 응답 속도가 느리고, “생각"하는 데 시간이 조금 더 걸렸습니다(약 8초).
  • Grok 4 코드: 진입점 없이 짧은 docstring을 포함한 짧은 코드를 제공했습니다.

Python 챌린지 4 - API 통합

챌린지 4 프롬프트:

requests 라이브러리를 사용하여 공개 API에서 현재 비트코인 가격을 USD로 가져와 출력합니다.

챌린지 4 GPT 5 코드:

 1import requests
 2
 3def get_bitcoin_price_usd():
 4    url = "https://api.coindesk.com/v1/bpi/currentprice/USD.json"
 5    try:
 6        response = requests.get(url, timeout=5)
 7        response.raise_for_status()  # Raise HTTPError for bad responses
 8        data = response.json()
 9        price = data["bpi"]["USD"]["rate"]
10        print(f"Current Bitcoin Price: ${price} USD")
11    except requests.exceptions.RequestException as e:
12        print(f"Error fetching Bitcoin price: {e}")
13    except (KeyError, ValueError) as e:
14        print(f"Error parsing response: {e}")
15
16if __name__ == "__main__":
17    get_bitcoin_price_usd()

챌린지 4 그록 4 코드:

 1import requests
 2
 3# Define the API endpoint
 4url = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd"
 5
 6# Fetch the data
 7response = requests.get(url)
 8
 9# Check if the request was successful
10if response.status_code == 200:
11    data = response.json()
12    bitcoin_price = data['bitcoin']['usd']
13    print(f"Current Bitcoin price in USD: ${bitcoin_price}")
14else:
15    print(f"Error fetching data: {response.status_code}")

챌린지 4 관찰 결과:

  • GPT 5 속도: 매우 빠른 응답, 거의 즉각적입니다.
  • GPT 5 코드: 진입점은 있지만 주석은 없는 짧고 세련된 코드를 제공했습니다.
  • Grok 4 속도: 응답 속도가 느리고, “생각"하는 데 시간이 조금 더 걸렸습니다(약 23초).
  • Grok 4 코드: 진입점은 없지만 주석은 있는 좀 더 짧은 코드를 제공했습니다.

Python 챌린지 5 - 웹 스크래핑

챌린지 5 프롬프트:

requests와 BeautifulSoup을 사용하여 https://news.ycombinator.com/ 에서 상위 5개 뉴스 헤드라인을 스크래핑하여 출력합니다.

챌린지 5 GPT 5 코드:

 1import requests
 2from bs4 import BeautifulSoup
 3
 4def get_top_hn_headlines(limit=5):
 5    url = "https://news.ycombinator.com/"
 6    try:
 7        response = requests.get(url, timeout=5)
 8        response.raise_for_status()
 9        
10        soup = BeautifulSoup(response.text, "html.parser")
11        headlines = [a.get_text() for a in soup.select(".titleline > a")]
12        
13        print(f"Top {limit} Hacker News Headlines:")
14        for i, title in enumerate(headlines[:limit], 1):
15            print(f"{i}. {title}")
16    except requests.exceptions.RequestException as e:
17        print(f"Error fetching Hacker News: {e}")
18
19if __name__ == "__main__":
20    get_top_hn_headlines()

챌린지 5 Grok 4 코드:

 1import requests
 2from bs4 import BeautifulSoup
 3
 4# Define the URL
 5url = 'https://news.ycombinator.com/'
 6
 7# Fetch the webpage
 8response = requests.get(url)
 9response.raise_for_status()  # Raise an error for bad status codes
10
11# Parse the HTML content
12soup = BeautifulSoup(response.text, 'html.parser')
13
14# Find the top 5 story elements
15stories = soup.find_all('tr', class_='athing')[:5]
16
17# Print the top 5 headlines
18print("Top 5 News Headlines from Hacker News:")
19for i, story in enumerate(stories, 1):
20    title_span = story.find('span', class_='titleline')
21    if title_span:
22        headline = title_span.find('a').text
23        print(f"{i}. {headline}")

챌린지 5 관찰 결과:

  • GPT 5 속도: 매우 빠른 응답, 거의 즉각적입니다.
  • GPT 5 코드: 진입점은 있지만 주석은 없는 짧고 세련된 코드를 제공했습니다.
  • Grok 4 속도: 응답 속도가 느리고, “생각” 시간이 약간 더 길었습니다(약 13초).
  • Grok 4 코드: 진입점은 없지만 주석은 있는 좀 더 긴 코드를 제공했습니다.

Python 챌린지 6 - 파일 압축

챌린지 6 프롬프트:

현재 디렉터리의 모든 .txt 파일을 ‘archive.zip’으로 압축하는 Python 스크립트를 작성하세요.

챌린지 6 GPT 5 코드:

 1import zipfile
 2import glob
 3import os
 4
 5def zip_text_files(output_zip="archive.zip"):
 6    txt_files = glob.glob("*.txt")
 7    if not txt_files:
 8        print("No .txt files found in the current directory.")
 9        return
10    
11    with zipfile.ZipFile(output_zip, "w") as zipf:
12        for file in txt_files:
13            zipf.write(file, os.path.basename(file))
14            print(f"Added: {file}")
15    
16    print(f"Created {output_zip} containing {len(txt_files)} files.")
17
18if __name__ == "__main__":
19    zip_text_files()

챌린지 6 Grok 4 코드:

 1import os
 2from zipfile import ZipFile
 3
 4# Get the current directory
 5current_dir = os.getcwd()
 6
 7# List all .txt files in the current directory
 8txt_files = [f for f in os.listdir(current_dir) if f.endswith('.txt')]
 9
10# Create a zip file and add the .txt files
11with ZipFile('archive.zip', 'w') as zipf:
12    for file in txt_files:
13        zipf.write(file)
14
15print(f"Successfully zipped {len(txt_files)} .txt files into 'archive.zip'.")

챌린지 6 관찰 결과:

  • GPT 5 속도: 매우 빠른 응답, 거의 즉각적입니다.
  • GPT 5 코드: 진입점은 있지만 주석은 없는 짧고 세련된 코드를 제공했습니다.
  • Grok 4 속도: 응답 속도가 느리고, “생각"하는 데 시간이 조금 더 걸렸습니다(약 10초).
  • Grok 4 코드: 진입점은 없지만 주석은 있는 짧은 코드를 제공했습니다.

Python 챌린지 7 - 이미지 처리

챌린지 7 프롬프트:

Pillow(PIL)를 사용하여 현재 디렉터리의 모든 JPEG 이미지를 800x600픽셀로 크기를 조정하고 ‘output’ 폴더에 저장합니다.

챌린지 7 GPT 5 코드:

 1import os
 2from PIL import Image
 3import glob
 4
 5def resize_jpeg_images(width=800, height=600, output_dir="output"):
 6    # Create output folder if it doesn't exist
 7    os.makedirs(output_dir, exist_ok=True)
 8
 9    # Find all .jpg and .jpeg files (case-insensitive)
10    jpeg_files = glob.glob("*.jpg") + glob.glob("*.jpeg") + glob.glob("*.JPG") + glob.glob("*.JPEG")
11
12    if not jpeg_files:
13        print("No JPEG images found in the current directory.")
14        return
15
16    for file in jpeg_files:
17        try:
18            with Image.open(file) as img:
19                img_resized = img.resize((width, height), Image.LANCZOS)
20                output_path = os.path.join(output_dir, os.path.basename(file))
21                img_resized.save(output_path, "JPEG")
22                print(f"Resized and saved: {output_path}")
23        except Exception as e:
24            print(f"Error processing {file}: {e}")
25
26if __name__ == "__main__":
27    resize_jpeg_images()

챌린지 7 Grok 4 코드:

 1import os
 2from PIL import Image
 3
 4# Get the current directory
 5current_dir = os.getcwd()
 6
 7# Create the output folder if it doesn't exist
 8output_folder = os.path.join(current_dir, 'output')
 9os.makedirs(output_folder, exist_ok=True)
10
11# List all JPEG files in the current directory (case-insensitive)
12jpeg_files = [f for f in os.listdir(current_dir) 
13              if f.lower().endswith(('.jpg', '.jpeg'))]
14
15# Resize each image and save to output folder
16resized_count = 0
17for file in jpeg_files:
18    try:
19        img_path = os.path.join(current_dir, file)
20        img = Image.open(img_path)
21        resized_img = img.resize((800, 600))
22        output_path = os.path.join(output_folder, file)
23        resized_img.save(output_path)
24        resized_count += 1
25    except Exception as e:
26        print(f"Error processing {file}: {e}")
27
28print(f"Successfully resized and saved {resized_count} JPEG images to the 'output' folder.")

도전과제 7 관찰 결과:

  • GPT 5 속도: 매우 빠른 응답, 거의 즉각적.
  • GPT 5 코드: 진입점이 있는 짧고 세련된 코드와 주석 제공.
  • Grok 4 속도: 응답 속도가 느림, “생각” 시간이 약간 더 길었음(약 10초).
  • Grok 4 코드: 진입점이 없는 약간 긴 코드와 주석 제공.

Python 도전과제 8 - 멀티스레딩

도전과제 8 프롬프트:

스레딩을 사용하여 주어진 URL에서 5개의 서로 다른 파일을 동시에 다운로드하는 Python 스크립트를 작성하세요.

도전과제 8 GPT 5 코드:

 1import os
 2from pathlib import Path
 3from urllib.parse import urlparse
 4from concurrent.futures import ThreadPoolExecutor, as_completed
 5
 6import requests
 7
 8CHUNK_SIZE = 1024 * 64  # 64KB
 9
10
11def unique_path(dest_dir: Path, filename: str) -> Path:
12    """Return a unique path inside dest_dir by appending (1), (2), ... if needed."""
13    dest = dest_dir / filename
14    if not dest.exists():
15        return dest
16    stem, suffix = os.path.splitext(filename)
17    i = 1
18    while True:
19        candidate = dest_dir / f"{stem} ({i}){suffix}"
20        if not candidate.exists():
21            return candidate
22        i += 1
23
24
25def filename_from_url(url: str, index: int) -> str:
26    """Get a safe filename from URL; fall back to file_{index} if missing."""
27    path = urlparse(url).path
28    name = os.path.basename(path).strip()
29    return name or f"file_{index}"
30
31
32def download_file(url: str, dest_dir: Path, index: int, timeout: int = 15) -> Path:
33    """Download a single file to dest_dir. Returns the saved path."""
34    dest_dir.mkdir(parents=True, exist_ok=True)
35    base_name = filename_from_url(url, index)
36    dest_path = unique_path(dest_dir, base_name)
37
38    headers = {"User-Agent": "python-threaded-downloader/1.0"}
39    with requests.get(url, stream=True, timeout=timeout, headers=headers) as r:
40        r.raise_for_status()
41        with open(dest_path, "wb") as f:
42            for chunk in r.iter_content(chunk_size=CHUNK_SIZE):
43                if chunk:  # filter out keep-alive chunks
44                    f.write(chunk)
45    return dest_path
46
47
48def download_concurrently(urls, out_dir="downloads", max_workers=5):
49    """Download given URLs concurrently using threads."""
50    dest_dir = Path(out_dir)
51    results = []
52    errors = []
53
54    with ThreadPoolExecutor(max_workers=max_workers) as executor:
55        future_to_url = {
56            executor.submit(download_file, url, dest_dir, i): url
57            for i, url in enumerate(urls, start=1)
58        }
59        for future in as_completed(future_to_url):
60            url = future_to_url[future]
61            try:
62                saved_path = future.result()
63                print(f"✅ Downloaded: {url} -> {saved_path}")
64                results.append(saved_path)
65            except Exception as e:
66                print(f"❌ Failed: {url} ({e})")
67                errors.append((url, e))
68    print(f"\nDone. {len(results)} succeeded, {len(errors)} failed.")
69    return results, errors
70
71
72if __name__ == "__main__":
73    # Replace these with your 5 URLs
74    urls = [
75        "https://example.com/file1.jpg",
76        "https://example.com/file2.pdf",
77        "https://example.com/file3.zip",
78        "https://example.com/file4.png",
79        "https://example.com/file5.mp4",
80    ]
81    download_concurrently(urls, out_dir="downloads", max_workers=5)

챌린지 8 Grok 4 코드:

 1import threading
 2import urllib.request
 3
 4def download_file(url, filename):
 5    """
 6    Downloads a file from the given URL and saves it with the specified filename.
 7    """
 8    try:
 9        urllib.request.urlretrieve(url, filename)
10        print(f"Downloaded {filename} from {url}")
11    except Exception as e:
12        print(f"Error downloading {url}: {e}")
13
14# List of 5 example URLs (replace with your actual URLs)
15urls = [
16    "https://www.example.com/file1.txt",
17    "https://www.example.com/file2.pdf",
18    "https://www.example.com/file3.jpg",
19    "https://www.example.com/file4.zip",
20    "https://www.example.com/file5.docx"
21]
22
23# Corresponding filenames to save the downloads
24filenames = [
25    "file1.txt",
26    "file2.pdf",
27    "file3.jpg",
28    "file4.zip",
29    "file5.docx"
30]
31
32# Create and start threads for concurrent downloads
33threads = []
34for url, filename in zip(urls, filenames):
35    thread = threading.Thread(target=download_file, args=(url, filename))
36    thread.start()
37    threads.append(thread)
38
39# Wait for all threads to complete
40for thread in threads:
41    thread.join()
42
43print("All downloads completed.")

챌린지 8 관찰 결과:

  • GPT 5 속도: 응답 속도가 느렸고, “생각"하는 데 시간이 조금 더 걸렸습니다(약 10초).
  • GPT 5 코드: 진입점이 있고 주석이 있는 길고 세련된 코드를 제공했습니다.
  • Grok 4 속도: 응답 속도가 더 느렸고, “생각"하는 데 시간이 조금 더 걸렸습니다(약 21초).
  • Grok 4 코드: 진입점이 없고 주석이 있는 더 짧은 코드를 제공했습니다.

Python 챌린지 9 - 데이터베이스 상호작용

챌린지 9 프롬프트:

SQLite 데이터베이스에 연결하고, ‘users’ 테이블을 생성하고, 샘플 데이터를 삽입하고, 모든 사용자를 쿼리합니다.

챌린지 9 GPT 5 코드:

 1import sqlite3
 2
 3def main():
 4    # Connect to (or create) the database
 5    conn = sqlite3.connect("example.db")
 6    cursor = conn.cursor()
 7
 8    # Create the users table if it doesn't exist
 9    cursor.execute("""
10        CREATE TABLE IF NOT EXISTS users (
11            id INTEGER PRIMARY KEY AUTOINCREMENT,
12            name TEXT NOT NULL,
13            email TEXT UNIQUE NOT NULL
14        )
15    """)
16
17    # Insert sample data
18    sample_users = [
19        ("Alice", "[email protected]"),
20        ("Bob", "[email protected]"),
21        ("Charlie", "[email protected]"),
22    ]
23
24    try:
25        cursor.executemany("INSERT INTO users (name, email) VALUES (?, ?)", sample_users)
26    except sqlite3.IntegrityError:
27        # Ignore duplicates if run multiple times
28        pass
29
30    # Commit changes
31    conn.commit()
32
33    # Query all users
34    cursor.execute("SELECT id, name, email FROM users")
35    users = cursor.fetchall()
36
37    print("Users in database:")
38    for user in users:
39        print(user)
40
41    # Close the connection
42    conn.close()
43
44if __name__ == "__main__":
45    main()

챌린지 9 Grok 4 코드:

 1import sqlite3
 2
 3# Connect to an in-memory SQLite database
 4conn = sqlite3.connect(':memory:')
 5cursor = conn.cursor()
 6
 7# Create the 'users' table
 8cursor.execute('''
 9    CREATE TABLE users (
10        id INTEGER PRIMARY KEY,
11        name TEXT,
12        age INTEGER
13    )
14''')
15
16# Insert sample data
17cursor.execute("INSERT INTO users (name, age) VALUES ('Alice', 30)")
18cursor.execute("INSERT INTO users (name, age) VALUES ('Bob', 25)")
19cursor.execute("INSERT INTO users (name, age) VALUES ('Charlie', 35)")
20
21# Commit the changes
22conn.commit()
23
24# Query all users
25cursor.execute("SELECT * FROM users")
26results = cursor.fetchall()
27
28# Print the results
29print("ID | Name | Age")
30print("----------------")
31for row in results:
32    print(f"{row[0]} | {row[1]} | {row[2]}")
33
34# Close the connection
35conn.close()

챌린지 9 관찰 결과:

  • GPT 5 속도: 매우 빠른 응답, 거의 즉각적입니다. “write or create” 대신 “connect…“라고 단도직입적으로 말했지만, 스크립트가 필요하다는 것을 이해했습니다.
  • GPT 5 코드: 진입점과 주석이 있는 길고 세련된 코드를 제공했습니다.
  • Grok 4 속도: 응답 속도가 느리고, “thought"가 약간 더 길었습니다(약 16초).
  • Grok 4 코드: 약간 더 짧은 코드를 제공했고, 처음으로 진입점과 주석을 포함했습니다. 흥미롭게도 여러 함수/테스트 이름이 ChatGPT 5 스타일을 반영하고 있습니다.

Python 챌린지 10 - 단위 테스트

챌린지 10 프롬프트:

함수 ‘is_prime(n)‘이 소수를 올바르게 식별하는지 확인하는 Python 단위 테스트를 작성하세요.

챌린지 10 GPT 5 코드:

 1import unittest
 2
 3# Example implementation of is_prime for testing purposes
 4# If you already have this function, you can remove this definition.
 5def is_prime(n):
 6    """Return True if n is a prime number, else False."""
 7    if n <= 1:
 8        return False
 9    if n <= 3:
10        return True
11    if n % 2 == 0 or n % 3 == 0:
12        return False
13    i = 5
14    while i * i <= n:
15        if n % i == 0 or n % (i + 2) == 0:
16            return False
17        i += 6
18    return True
19
20
21class TestIsPrime(unittest.TestCase):
22    def test_primes(self):
23        primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
24        for p in primes:
25            with self.subTest(p=p):
26                self.assertTrue(is_prime(p), f"{p} should be prime")
27
28    def test_non_primes(self):
29        non_primes = [0, 1, 4, 6, 8, 9, 10, 12, 15, 20, 25]
30        for n in non_primes:
31            with self.subTest(n=n):
32                self.assertFalse(is_prime(n), f"{n} should not be prime")
33
34if __name__ == "__main__":
35    unittest.main()

챌린지 10 Grok 4 코드:

 1import unittest
 2
 3# Assuming the is_prime function is defined in a module named prime_checker
 4# Replace 'prime_checker' with the actual module name where is_prime is defined
 5from prime_checker import is_prime
 6
 7class TestIsPrime(unittest.TestCase):
 8    def test_prime_numbers(self):
 9        """Test that prime numbers are correctly identified."""
10        primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
11        for num in primes:
12            with self.subTest(num=num):
13                self.assertTrue(is_prime(num), f"{num} should be prime")
14
15    def test_non_prime_numbers(self):
16        """Test that non-prime numbers are correctly identified."""
17        non_primes = [0, 1, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28]
18        for num in non_primes:
19            with self.subTest(num=num):
20                self.assertFalse(is_prime(num), f"{num} should not be prime")
21
22    def test_negative_numbers(self):
23        """Test that negative numbers are not considered prime."""
24        negatives = [-1, -2, -3, -5, -7]
25        for num in negatives:
26            with self.subTest(num=num):
27                self.assertFalse(is_prime(num), f"{num} should not be prime")
28
29    def test_one_and_zero(self):
30        """Explicitly test 0 and 1, which are not prime."""
31        self.assertFalse(is_prime(0))
32        self.assertFalse(is_prime(1))
33
34if __name__ == '__main__':
35    unittest.main()

도전과제 10 관찰 결과:

  • GPT 5 속도: 매우 빠른 응답, 거의 즉각적.
  • GPT 5 코드: 진입점과 주석이 포함된 길고 세련된 코드 제공.
  • Grok 4 속도: 응답 속도가 느림, “생각” 시간이 약간 더 길었음(약 12초).
  • Grok 4 코드: 진입점과 주석이 포함된 코드를 처음으로 조금 더 짧게 제공. 흥미롭게도 함수 이름이 ChatGPT 5와 동일함.

평가 기준

각 AI는 다음 기준으로 평가됩니다.

  • 코드 정확성: 큰 수정 없이 작동하는가?
  • 가독성: 코드가 깔끔하고 주석이 잘 작성되어 있는가?
  • 효율성: 최적의 방법을 사용하는가?
  • 오류 처리: 발생할 수 있는 오류를 예측하는가?
  • 설명 가능성: 명확한 추론을 제공하는가?

예비 관찰

이전 및 현재 경험:

  • ChatGPT 5는 더 자세하고 잘 문서화된 코드를 훨씬 빠르게 제공하는 경향이 있습니다.
  • Grok 4는 미니멀리즘과 느린 응답 속도를 선호하며, 때로는 주석을 생략하기도 합니다.

두 언어 모두 표준 작업에는 뛰어나지만, Grok은 다단계 추론 프롬프트에 어려움을 겪을 수 있습니다.

10가지 과제에서 두드러진 점

  • 즉각적인 준수: GPT-5는 과제를 충실히 수행했습니다(예: BTC API). Grok 4는 때때로 방향을 벗어났습니다(4번 과제).
  • 진입점 및 구조: GPT-5는 진입점과 헬퍼를 일관되게 사용했습니다. Grok 4는 진입점 없이 단일 파일 스크립트를 작성하는 경우가 많았습니다.
  • 오류 처리: GPT-5는 timeouts/raise_for_status/try-except를 더 자주 추가했습니다. Grok 4는 최소화하는 경향이 있었습니다.
  • 종속성 및 가정: GPT-5는 가능한 경우 stdlib를 사용했고, Grok 4는 pandas 또는 더 간단한 urllib 기본값을 사용했습니다.
  • 데이터 모델 가정: GPT-5는 추론된 필드와 계산된 값(수량 × 가격)을 사용했고, Grok 4는 사전 집계된 열을 가정했습니다.
  • 알고리즘 주의: 두 경우 모두 논리 작업을 해결했습니다. GPT-5의 예제에는 사소한 변수 버그가 있었고, Grok 4의 HN 예제에는 구문 오타가 있었습니다.
  • 성능 포스처: GPT-5는 다운로드에 스트리밍 + 스레드 풀을 사용했고, Grok 4는 원시 스레드 + urlretrieve(더 단순하지만 덜 안정적)를 사용했습니다.

평결

두 도구 모두 기능적인 Python 코드를 작성할 수 있지만, 개발자의 선호도에 따라 선택이 달라질 수 있습니다.

  • 상세한 설명, 단계별 추론, 빠른 코드 생성, 풍부한 주석을 중시한다면 ChatGPT 5를 선택하세요.
  • 간결하고 간단한 코드, 불필요한 부분은 최소화하고 느린 코드 생성을 선호한다면 Grok 4를 선택하세요.

솔직히 ChatGPT 5를 선호하는데, 더 좋고 자세한 Python 코드로 훨씬 빠르게 응답하기 때문입니다. 엘론 머스크에게는 죄송합니다.

자주 묻는 질문(FAQ)

**초보자에게는 OpenAI ChatGPT 5와 Grok 4 중 어느 것이 더 나을까요? ChatGPT 5. 더 많은 설명을 제공하고, 더 안전한 기본값(시간 초과, 오류 처리)을 포함하며, 더 깔끔한 구조를 사용합니다.

이 테스트에서 어느 쪽의 코드 문제가 더 적었나요? 전반적으로 ChatGPT 5입니다. Grok 4는 스크래핑 과정에서 간헐적으로 프롬프트 드리프트와 사소한 구문 오류가 발생했습니다.

어느 쪽이 더 빠릅니까? 실행 결과, ChatGPT 5가 평균적으로 더 빠르게 응답했습니다. 각 과제별 시간이 포함되어 있습니다.

생성된 코드를 검토해야 합니까? 네. 두 모델 모두 사소한 실수가 발생할 수 있으므로 항상 테스트를 실행하고 I/O 및 네트워크 코드에 대한 가드레일을 추가하십시오.

어느 쪽이 파일, 이미지 및 네트워킹을 더 안정적으로 처리합니까? ChatGPT 5. 진입점, 시간 초과, 스트리밍 및 향상된 이미지 리샘플링 기능이 추가된 경향이 있습니다.

Grok 4의 장점이 있습니까? 네, 이미 컨텍스트를 알고 있고 최소한의 출력을 원할 때 더 빠르고 간결한 스크립트를 사용할 수 있습니다.

어떤 프롬프트 스타일이 가장 효과적이었습니까? 입출력, 라이브러리 및 예외 사례에 대해 명확하게 설명하십시오(예: ‘시간 초과가 있는 요청 사용, JSON 구문 분석 오류 출력’).

두 모델 모두 프로덕션 코드에 사용할 수 있나요? 두 모델을 대체재가 아닌 가속기로 사용하세요. 테스트, 린팅, 보안 검토를 파이프라인에 포함하세요.