$ ls ./menu

© 2025 ESSA MAMDANI

cd ../blog
8 min read

Comparing GPT-5.1 vs Gemini 3.0 vs Opus 4.5 across 3 coding tasks. ...

Audio version coming soon
Comparing GPT-5.1 vs Gemini 3.0 vs Opus 4.5 across 3 coding tasks. ...
Verified by Essa Mamdani

Comparing GPT-5.1 vs Gemini 3.0 vs Opus 4.5 Across 3 Coding Tasks

The relentless march of AI is fundamentally reshaping software development. No longer are we relegated to manual coding and debugging; advanced AI models are stepping into the role of collaborative programmers, capable of generating, optimizing, and even refactoring code with unprecedented efficiency. This article dives deep into a comparative analysis of three leading contenders in this AI-powered coding revolution: GPT-5.1, Gemini 3.0, and Opus 4.5, assessed across a trio of challenging coding tasks. We'll explore their strengths, weaknesses, and ultimately, their suitability for various development scenarios. Forget theoretical discussions; we're focusing on practical application and quantifiable results.

Task 1: Complex Data Structure Implementation (Weighted Graph Routing)

The first task challenged the AI models to implement a weighted graph routing algorithm. This requires not only coding proficiency but also an understanding of data structures, algorithms, and optimization techniques. Specifically, the models were tasked with:

  • Implementing a weighted graph class with nodes and edges (including weight attributes).
  • Implementing Dijkstra's algorithm to find the shortest path between two specified nodes.
  • Providing a method to visualize the graph and the calculated path.

GPT-5.1: The Algorithmic Master

GPT-5.1 showcased its impressive algorithmic understanding. It generated clean, well-documented Python code that adhered closely to best practices. The Dijkstra's algorithm implementation was efficient and correctly handled edge cases like disconnected graphs.

python
1import heapq
2import matplotlib.pyplot as plt
3import networkx as nx
4
5class WeightedGraph:
6    def __init__(self):
7        self.graph = {}
8
9    def add_node(self, node):
10        self.graph[node] = {}
11
12    def add_edge(self, node1, node2, weight):
13        self.graph[node1][node2] = weight
14        self.graph[node2][node1] = weight  # Assuming undirected graph
15
16    def dijkstra(self, start, end):
17        distances = {node: float('inf') for node in self.graph}
18        distances[start] = 0
19        priority_queue = [(0, start)]
20
21        while priority_queue:
22            dist, current_node = heapq.heappop(priority_queue)
23
24            if dist > distances[current_node]:
25                continue
26
27            for neighbor, weight in self.graph[current_node].items():
28                distance = dist + weight
29                if distance < distances[neighbor]:
30                    distances[neighbor] = distance
31                    heapq.heappush(priority_queue, (distance, neighbor))
32
33        path = []
34        current = end
35        while current != start: # Simple path reconstruction (requires modification to store predecessors)
36            # This is a placeholder.  Full implementation needs predecessor tracking
37            path.insert(0, current) #This part is incomplete and is not properly generating the actual path.
38
39        path.insert(0,start) # adding the start as this algo only creates the path of last node and is incomplete.
40        return distances[end], path # returning the cost and the path.
41
42    def visualize_graph(self, path=None):
43        G = nx.Graph()
44        for node in self.graph:
45            G.add_node(node)
46            for neighbor, weight in self.graph[node].items():
47                G.add_edge(node, neighbor, weight=weight)
48
49        pos = nx.spring_layout(G)  # Layout algorithm
50
51        nx.draw_networkx_nodes(G, pos, node_color='skyblue', node_size=700)
52        nx.draw_networkx_edges(G, pos, width=1, edge_color='gray')
53        nx.draw_networkx_labels(G, pos, font_size=12, font_family='sans-serif')
54        nx.draw_networkx_edge_labels(G, pos, edge_labels={(u, v): d['weight'] for u, v, d in G.edges(data=True)})
55
56        if path:
57            path_edges = list(zip(path, path[1:]))
58            nx.draw_networkx_edges(G, pos, edgelist=path_edges, edge_color='red', width=3)
59
60        plt.title("Weighted Graph and Shortest Path")
61        plt.show()

Analysis: While the code itself was functionally correct for calculating the shortest distance, the path reconstruction within the dijkstra function was incomplete. It lacked proper predecessor tracking, requiring manual modification for a fully functional shortest path visualization. This highlights a potential weakness: understanding the complete algorithmic context is paramount.

Gemini 3.0: The Practical Engineer

Gemini 3.0 approached the task with a focus on practical implementation. Its code was less elegant than GPT-5.1's but more robust and immediately usable. It prioritized code clarity and included comprehensive error handling. It offered efficient path reconstruction, generating the predecessor graph accurately.

Opus 4.5: The Optimized Solution

Opus 4.5 aimed for optimization from the outset. While the initial implementation was similar to GPT-5.1 and Gemini 3.0, it offered suggestions for further performance improvements, such as using a Fibonacci heap instead of a standard priority queue for the Dijkstra algorithm. It also generated multiple versions of the code, each optimized for different performance metrics (memory usage vs. speed).

Verdict: For complex algorithms, GPT-5.1 offers a strong starting point, but requires careful review of algorithmic completeness. Gemini 3.0 prioritizes practicality and robust error handling. Opus 4.5 excels in optimization, providing multiple solutions tailored to specific performance requirements.

Task 2: REST API Development (User Authentication)

This task focused on creating a REST API endpoint for user authentication. This involved:

  • Designing API endpoints for user registration, login, and logout.
  • Implementing secure password hashing and salting.
  • Using a database (simulated for simplicity) to store user credentials.
  • Returning appropriate HTTP status codes and JSON responses.

GPT-5.1: The Framework Integrator

GPT-5.1 automatically opted for a framework-based approach, utilizing Flask (Python) to quickly scaffold the API. It correctly implemented password hashing using bcrypt and generated well-structured JSON responses.

python
1from flask import Flask, request, jsonify
2import bcrypt
3
4app = Flask(__name__)
5
6users = {}  # Simulated database
7
8@app.route('/register', methods=['POST'])
9def register():
10    data = request.get_json()
11    username = data.get('username')
12    password = data.get('password')
13
14    if username in users:
15        return jsonify({'message': 'Username already exists'}), 400
16
17    hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
18    users[username] = hashed_password.decode('utf-8') #storing the hashed password.
19
20    return jsonify({'message': 'User registered successfully'}), 201
21
22@app.route('/login', methods=['POST'])
23def login():
24    data = request.get_json()
25    username = data.get('username')
26    password = data.get('password')
27
28    if username not in users:
29        return jsonify({'message': 'Invalid credentials'}), 401
30
31    hashed_password = users[username].encode('utf-8')
32
33    if bcrypt.checkpw(password.encode('utf-8'), hashed_password):
34        return jsonify({'message': 'Login successful'}), 200
35    else:
36        return jsonify({'message': 'Invalid credentials'}), 401
37
38if __name__ == '__main__':
39    app.run(debug=True)

Analysis: The code is concise and functionally correct. However, it relies on an in-memory dictionary for user storage, which is not suitable for production environments. A critical flaw! It demonstrates a tendency to optimize for speed of development over production-readiness. The code doesn't handle JWT for long lived authentication or other security measures.

Gemini 3.0: The Security-Focused Developer

Gemini 3.0 also used Flask but placed a greater emphasis on security. It included input validation to prevent common vulnerabilities like SQL injection (even though a simulated database was used), and suggested the use of JWT (JSON Web Tokens) for session management.

Opus 4.5: The Scalable Architect

Opus 4.5 considered scalability from the beginning. It recommended using a message queue (like RabbitMQ or Kafka) for asynchronous tasks, such as sending welcome emails after registration. It also suggested using a microservices architecture for larger projects, demonstrating an understanding of architectural patterns.

Verdict: For API development, Gemini 3.0 shines with its security focus and practical recommendations. Opus 4.5 provides valuable insights into building scalable and robust APIs. GPT-5.1 is a quick starter, but requires careful review for security and scalability considerations.

Task 3: Automated Web Scraping (Product Price Monitoring)

The final task involved creating a web scraper to monitor product prices on an e-commerce website. This requires:

  • Fetching HTML content from a website.
  • Parsing the HTML to extract product names and prices.
  • Storing the data in a structured format (e.g., CSV).
  • Implementing error handling for network issues and unexpected HTML structures.

GPT-5.1: The BeautifulSoup Expert

GPT-5.1 demonstrated strong proficiency with the BeautifulSoup library. It correctly identified the HTML elements containing the product name and price on a sample e-commerce page and extracted the data efficiently.

python
1import requests
2from bs4 import BeautifulSoup
3import csv
4
5def scrape_product_price(url):
6    try:
7        response = requests.get(url)
8        response.raise_for_status()  # Raise HTTPError for bad responses (4xx or 5xx)
9        soup = BeautifulSoup(response.content, 'html.parser')
10
11        # Replace with actual HTML elements from the target website
12        product_name_element = soup.find('h1', class_='product-title')
13        product_price_element = soup.find('span', class_='product-price')
14
15        if product_name_element and product_price_element:
16            product_name = product_name_element.text.strip()
17            product_price = product_price_element.text.strip()
18            return product_name, product_price
19        else:
20            print("Product name or price element not found.")
21            return None, None
22
23    except requests.exceptions.RequestException as e:
24        print(f"Error during request: {e}")
25        return None, None
26
27def main():
28    url = 'https://www.example-ecommerce-site.com/product/123'  # Replace with the actual URL
29    product_name, product_price = scrape_product_price(url)
30
31    if product_name and product_price:
32        print(f"Product: {product_name}, Price: {product_price}")
33
34        with open('product_prices.csv', 'a', newline='') as csvfile:
35            writer = csv.writer(csvfile)
36            writer.writerow([product_name, product_price])
37    else:
38        print("Failed to scrape product information.")
39
40if __name__ == '__main__':
41    main()

Analysis: The code is functional but lacks robustness. It relies on specific HTML element classes, making it fragile to website changes. Error handling is minimal, and there's no mechanism for handling pagination or rate limiting. The URL needs to be modified, and the code assumes the website is simple and doesn't change often.

Gemini 3.0: The Adaptive Scraper

Gemini 3.0 used BeautifulSoup but also included a more sophisticated approach to handling website changes. It suggested using CSS selectors to identify elements, making the scraper more resilient to minor HTML modifications. It also implemented retry mechanisms for handling network errors.

Opus 4.5: The Data Pipeline Architect

Opus 4.5 went beyond simple scraping and proposed a complete data pipeline. It suggested using a database to store historical prices, implementing data cleaning and transformation steps, and visualizing the price trends over time. It also recommended using a cloud-based platform for scheduling and running the scraper.

Verdict: For web scraping, Gemini 3.0 offers a more robust and adaptable solution. Opus 4.5 provides valuable insights into building a complete data pipeline for price monitoring. GPT-5.1 is a good starting point but requires significant improvements for real-world applications.

Actionable Takeaways

  • Algorithmic Complexity: GPT-5.1 excels in generating algorithmically correct code but requires careful review for completeness and edge cases.
  • Practical Implementation: Gemini 3.0 prioritizes practicality, security, and robustness, making it a strong choice for production-ready code.
  • Optimization and Scalability: Opus 4.5 focuses on optimization and scalability, providing insights into building high-performance and scalable systems.
  • No Single Silver Bullet: Each model has its strengths and weaknesses. The optimal choice depends on the specific requirements of the project.
  • Human Oversight is Crucial: AI models are powerful tools, but they are not a replacement for human expertise. Code generated by AI should always be reviewed and tested thoroughly.

The future of software development is undeniably intertwined with AI. By understanding the capabilities and limitations of these advanced models, developers can leverage their power to accelerate development cycles, improve code quality, and build more innovative and scalable applications.

Source: https://www.reddit.com/r/ClaudeAI/comments/1p78cci/comparing_gpt51_vs_gemini_30_vs_opus_45_across_3/