Сравнение Gemini 3 и Claude Opus 4.5
Наступил 2026 год, а значит необходимо обновить мой код, который вычисляет является ли текущий день праздничным в Казахстане или нет. У нас в стране есть сайт электронного правительства, где ежегодно публикуется календарь праздников - Праздничные и выходные дни в Республике Казахстан. Уже второй год подряд я использую Agentic Coding для написания необходимой мне функции на Python. И второй год подряд лучше всех справляется LLM модель от Google - Gemini 3.
В начале прошлого года у меня появилась необходимость учитывать является ли текущий день праздничным или нет, и тогда мне в голову пришла идея скормить изображение календаря LLM моделям и на базе этой картинке получить готовую Python-функцию. На тот момент рабочий вариант функции мне удалось получить только от Gemini, причем совсем с незначительными правками с моей стороны. Модели от Anthropic выдавали нерабочий код, была даже ситуация, когда Sonnet выплюнула мне огромный словарь, где ключ это конкретная дата, а значение типа bool определяет выходной это или нет. С тех пор прошел почти год, мир увидел самую продвинутую модель для кодинга от Anthropic Opus 4.5. В связи с наступлением нового года снова возникла идея скормить изображение и получить на выходе готовый код.
Вот промт, который я использую для двух моделей
Based on the provided image calendar for 2026 year, write a python function which returns whether the particular day is a day off or not. Working day cells have light background, day offs are red/orange filled cells.
Простой промт, описывающий что необходимо сделать с небольшими подсказками, чтобы модельке было легче понять где рабочий день, а где выходной.
Результат
Claude Sonnet 4.5
def is_day_off(day: int, month: int, year: int = 2026) -> bool:
"""
Check if a particular day is a day off in Kazakhstan for 2026.
Args:
day: Day of the month (1-31)
month: Month (1-12)
year: Year (default: 2026)
Returns:
True if the day is a day off (weekend or public holiday), False otherwise
"""
if year != 2026:
raise ValueError("This function only works for year 2026")
# Define all days off for each month in 2026
# Based on the calendar: red/orange cells are days off
days_off_by_month = {
1: [1, 2, 3, 4, 10, 11, 17, 18, 24, 25, 31], # January
2: [1, 7, 8, 14, 15, 21, 22, 28], # February
3: [1, 7, 8, 14, 15, 21, 22, 23, 24, 28, 29], # March
4: [4, 5, 11, 12, 18, 19, 25, 26], # April
5: [1, 2, 3, 7, 9, 10, 11, 16, 17, 23, 24, 27, 30, 31], # May
6: [6, 7, 13, 14, 20, 21, 27, 28], # June
7: [4, 5, 6, 11, 12, 18, 19, 25, 26], # July
8: [1, 2, 8, 9, 15, 16, 22, 23, 29, 30, 31], # August
9: [5, 6, 12, 13, 19, 20, 26, 27], # September
10: [3, 4, 10, 11, 17, 18, 24, 25, 26, 31], # October
11: [1, 7, 8, 14, 15, 21, 22, 28, 29], # November
12: [5, 6, 12, 13, 16, 19, 20, 26, 27], # December
}
# Validate input
if month < 1 or month > 12:
raise ValueError(f"Invalid month: {month}. Must be between 1 and 12")
if day < 1 or day > 31:
raise ValueError(f"Invalid day: {day}. Must be between 1 and 31")
# Check if the day exists in the given month
try:
date(year, month, day)
except ValueError:
raise ValueError(f"Invalid date: {year}-{month:02d}-{day:02d}")
return day in days_off_by_month.get(month, [])Claude Opus 4.5
from datetime import date, timedelta
from typing import Union
def is_day_off(check_date: Union[date, str]) -> bool:
"""
Check if a given date is a day off in Kazakhstan for 2026.
Args:
check_date: Either a date object or a string in 'YYYY-MM-DD' format
Returns:
True if the date is a day off, False if it's a working day
Raises:
ValueError: If the date is not in 2026 or invalid format
"""
if isinstance(check_date, str):
check_date = date.fromisoformat(check_date)
if check_date.year != 2026:
raise ValueError("This calendar is only valid for 2026")
# Set of all days off in 2026 (month, day)
# Extracted from the Kazakhstan 2026 holiday calendar
days_off = {
# January - New Year holidays
(1, 1), (1, 2), (1, 3), (1, 4), # Thu-Sun (New Year)
(1, 7), # Wed - Orthodox Christmas
(1, 10), (1, 11), # Sat-Sun
(1, 17), (1, 18), # Sat-Sun
(1, 24), (1, 25), # Sat-Sun
(1, 31), # Sat
# February
(2, 1), # Sun
(2, 7), (2, 8), # Sat-Sun
(2, 14), (2, 15), # Sat-Sun
(2, 21), (2, 22), # Sat-Sun
(2, 28), # Sat
# March
(3, 1), # Sun
(3, 7), (3, 8), # Sat-Sun (March 8 - International Women's Day)
(3, 14), (3, 15), # Sat-Sun
(3, 21), (3, 22), # Sat-Sun (March 21-23 - Nauryz)
(3, 23), # Mon - Nauryz holiday
(3, 28), (3, 29), # Sat-Sun
# April
(4, 4), (4, 5), # Sat-Sun
(4, 11), (4, 12), # Sat-Sun
(4, 18), (4, 19), # Sat-Sun
(4, 25), (4, 26), # Sat-Sun
# May
(5, 1), # Fri - Kazakhstan People's Unity Day
(5, 2), (5, 3), # Sat-Sun
(5, 7), # Thu - Defender of the Fatherland Day
(5, 9), (5, 10), # Sat-Sun (May 9 - Victory Day)
(5, 16), (5, 17), # Sat-Sun
(5, 23), (5, 24), # Sat-Sun
(5, 27), # Wed - Eid al-Fitr (Oraza Ait) - variable Islamic holiday
(5, 30), (5, 31), # Sat-Sun
# June
(6, 6), (6, 7), # Sat-Sun
(6, 13), (6, 14), # Sat-Sun
(6, 20), (6, 21), # Sat-Sun
(6, 27), (6, 28), # Sat-Sun
# July
(7, 4), (7, 5), # Sat-Sun
(7, 6), # Mon - Capital City Day
(7, 11), (7, 12), # Sat-Sun
(7, 18), (7, 19), # Sat-Sun
(7, 25), (7, 26), # Sat-Sun
# August
(8, 1), (8, 2), # Sat-Sun
(8, 3), # Mon - Eid al-Adha (Kurban Ait) - variable Islamic holiday
(8, 8), (8, 9), # Sat-Sun
(8, 15), (8, 16), # Sat-Sun
(8, 22), (8, 23), # Sat-Sun
(8, 29), (8, 30), # Sat-Sun (Aug 30 - Constitution Day)
# September
(9, 5), (9, 6), # Sat-Sun
(9, 12), (9, 13), # Sat-Sun
(9, 19), (9, 20), # Sat-Sun
(9, 26), (9, 27), # Sat-Sun
# October
(10, 3), (10, 4), # Sat-Sun
(10, 10), (10, 11), # Sat-Sun
(10, 17), (10, 18), # Sat-Sun
(10, 24), (10, 25), # Sat-Sun (Oct 25 - Republic Day)
(10, 31), # Sat
# November
(11, 1), # Sun
(11, 7), (11, 8), # Sat-Sun
(11, 14), (11, 15), # Sat-Sun
(11, 21), (11, 22), # Sat-Sun
(11, 28), (11, 29), # Sat-Sun
# December
(12, 5), (12, 6), # Sat-Sun
(12, 12), (12, 13), # Sat-Sun
(12, 16), # Wed - Independence Day
(12, 19), (12, 20), # Sat-Sun
(12, 26), (12, 27), # Sat-Sun
}
return (check_date.month, check_date.day) in days_off
Радует, что обе модели выдали рабочий код в отличии от прошлогоднего результата, где у меня не получилось с первого раза добиться желаемого. Но обе функции повторяют один и тот же паттерн - создают массивы выходных дней из-за чего код получается более громоздким. Что же на это скажет LLM от Google?
Gemini 3
from datetime import date
def is_dayoff_kazakhstan_2026(check_date: date):
"""
Returns True if the date is a day-off in Kazakhstan 2026,
based on the provided visual calendar.
"""
if check_date.year != 2026:
return "This function only supports the year 2026."
# 1. Check for weekends (Saturday = 5, Sunday = 6)
if check_date.weekday() >= 5:
return True
# 2. List of specific holidays and transferred rest days (Red/Orange cells)
# Format: (Month, Day)
holidays_2026 = {
(1, 1), (1, 2), (1, 7), # January
(3, 8), (3, 9), (3, 21), (3, 22),
(3, 23), (3, 24), (3, 25), # March (Nauryz)
(5, 1), (5, 7), (5, 9), (5, 11), # May
(7, 6), # July
(8, 30), (8, 31), # August
(25, 10), (26, 10), # October
(12, 16) # December
}
if (check_date.month, check_date.day) in holidays_2026:
return True
return FalseКак по мне у Gemini 3 получилось сгенерировать лаконичный и понятный код без лишних данных. Модель показала себя как "думающая" в отличии от Sonnet 4.5 и Opus 4.5. Мне нравится, что код не дублирует выходные дни (субботу и воскресенье), а проверяет их через условие:
if check_date.weekday() >= 5:
return TrueВывод
В этом ни на что не претендующем тесте более выигрышно явно смотрится Gemini 3. Думаю причина в том, что у Gemini более продвинутые способности по распознаванию изображений чем у моделей Anthropic. Код от Opus и Sonnet показался мне более многословным и менее читабельным, но прогресс в любом случае на лицо. По итогу я взял в продакшен решение от Gemini как самое оптимальное решение как с точки зрения читабельности так и производительности.