работает не так, как ожидал • Никаких ошибок нет # settings.py SUBSCRIPTION = { ‘duration’: timedelta(days=30), ‘price’: Decimal(100), } # service.py subscriptions = getattr( settings, ‘SUBSCRIPTIONS’, DEFAULT_SETTINGS )
работает не так, как ожидал • Никаких ошибок нет • В чём ошибка? # settings.py SUBSCRIPTION = { ‘duration’: timedelta(days=30), ‘price’: Decimal(100), } # service.py subscriptions = getattr( settings, ‘SUBSCRIPTIONS’, DEFAULT_SETTINGS )
работает не так, как ожидал • Никаких ошибок нет • В чём ошибка? • Проверяю - забыл одну букву # settings.py SUBSCRIPTIONS = { ‘duration’: timedelta(days=30), ‘price’: Decimal(100), } # service.py subscriptions = getattr( settings, ‘SUBSCRIPTIONS’, DEFAULT_SETTINGS )
ошибку, что такая строка уже существует (psycopg.errors.UniqueViolation) duplicate key value violates unique constraint "ix_tag_name" DETAIL: Key (lower('name'::text))=(name) already exists. [SQL: INSERT INTO tag (name, id) VALUES (%(name)s::VARCHAR, nextval('tag_id_seq')) RETURNING tag.id] [parameters: {'name': 'ai'}]
ошибку, что такая строка уже существует • А строки разные! (psycopg.errors.UniqueViolation) duplicate key value violates unique constraint "ix_tag_name" DETAIL: Key (lower('name'::text))=(name) already exists. [SQL: INSERT INTO tag (name, id) VALUES (%(name)s::VARCHAR, nextval('tag_id_seq')) RETURNING tag.id] [parameters: {'name': 'ai'}]
func.lower('name'), unique=True), ) • Пытаюсь записать несколько строк в БД • Получаю ошибку, что такая строка уже существует • А строки разные! • Смотрю, что уже есть в таблице - а там ничего! • А потому что “name” - это не название колонки, а строка!
tuple[int, int] для интервалов - это не по- сеньорски epoch = (100, 200) jobs = Jobs.objects.filter( block__gte=epoch[0], block__lt=epoch[1], ) .order_by("block")
tuple[int, int] для интервалов - это не по- сеньорски • Есть же специальный тип: range epoch = (100, 200) jobs = Jobs.objects.filter( block__gte=epoch[0], block__lt=epoch[1], ) .order_by("block")
tuple[int, int] для интервалов - это не по- сеньорски • Есть же специальный тип: range • Время рефакторинга! epoch = (100, 200) jobs = Jobs.objects.filter( block__gte=epoch[0], block__lt=epoch[1], ) .order_by("block")
tuple[int, int] для интервалов - это не по- сеньорски • Есть же специальный тип: range • Время рефакторинга! • Всё сломалось epoch = range(100, 201) jobs = Jobs.objects.filter( block__gte=epoch[0], block__lt=epoch[1], ) .order_by("block")
tuple[int, int] для интервалов - это не по- сеньорски • Есть же специальный тип: range • Время рефакторинга! • Всё сломалось • А потому что [1] теперь не то, чем было! epoch = range(100, 201) jobs = Jobs.objects.filter( block__gte=epoch[0], block__lt=epoch[1], ) .order_by("block")
tuple[int, int] для интервалов - это не по- сеньорски • Есть же специальный тип: range • Время рефакторинга! • Всё сломалось • А потому что [1] теперь не то, чем было! epoch = range(100, 201) jobs = Jobs.objects.filter( block__gte=epoch.start, block__lt=epoch.stop, ) .order_by("block")
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
путешествовать во времени и создавать параллельные вселенные • Просто смотрим на ветки VCS - и всегда всё понятно • А если непонятно - наши коллеги всегда напишут понятные сообщения
config["configurable"]["message_history"].messages + historic_messages = await config["configurable"]["message_history"].aget_messages() Почему? • Копипаста • Метод называется “messages”, а не “get_messages”
Но ещё больше любят возвращать результат • Но коды ошибок - это как-то сложно • Поэтому… try: is_success, msg = do_stuff() if not is_success: exc_class = parse_error(msg) raise exc_class(msg) except Exception: # handle exception
Но ещё больше любят возвращать результат • Но коды ошибок - это как-то сложно • Поэтому… try: is_success, msg = do_stuff() if not is_success: exc_class = parse_error(msg) raise exc_class(msg) except Exception: # handle exception
время, за сколько нам придёт ответ • Что может пойти не так? before_time = now() await send_request(job) start_time = now() response = await ws.recv() response_time = now() score = response_time - start_time
время, за сколько нам придёт ответ • Что может пойти не так? before_time = now() await send_request(job) start_time = now() response = await ws.recv() response_time = now() score = response_time - start_time
минут, пока скачаются сотни зависимостей • Не переживайте! Вряд ли хоть в одной из них есть уязвимости > npx create-next-app added 360 packages in 3m > npx create-remix 631 > npx create-gatsby 864 > npx create-react-app 1480
минут, пока скачаются сотни зависимостей • Не переживайте! Вряд ли хоть в одной из них есть уязвимости > npx create-next-app added 360 packages in 3m > npx create-remix 631 > npx create-gatsby 864 > npx create-react-app 1480
минут, пока скачаются сотни зависимостей • Не переживайте! Вряд ли хоть в одной из них есть уязвимости > npx create-next-app added 360 packages in 3m > npx create-remix 631 > npx create-gatsby 864 > npx create-react-app 1480
минут, пока скачаются сотни зависимостей • Не переживайте! Вряд ли хоть в одной из них есть уязвимости > npx create-next-app added 360 packages in 3m > npx create-remix 631 > npx create-gatsby 864 > npx create-react-app 1480
Восстанавливаемся из бэкапа: pg_restore postgres < dump.sql pg_restore: error: input file does not appear to be a valid archive • psql postgres < dump.sql
параметры • docker build --build-arg VERSION=123 FROM alpine AS base RUN echo "Base image: $VERSION" FROM base ARG VERSION RUN echo "Child image: $VERSION" #5 Base image: #6 Child image: 123 1 2
параметры • docker build --build-arg VERSION=123 FROM alpine AS base ARG VERSION RUN echo "Base image: $VERSION" FROM base RUN echo "Child image: $VERSION" #5 Base image: 123 #6 Child image: 123 1 2
параметры • docker build --build-arg VERSION=123 ARG VERSION FROM alpine:{$VERSION} AS base RUN echo "Base image: $VERSION" FROM base RUN echo "Child image: $VERSION" #5 Base image: #6 Child image: 1 2
параметры • docker build --build-arg VERSION=123 ARG VERSION FROM alpine:{$VERSION} AS base RUN echo "Base image: $VERSION" FROM base RUN echo "Child image: $VERSION" #5 Base image: #6 Child image: 1 2
параметры • docker build --build-arg VERSION=123 ARG VERSION FROM alpine:{$VERSION} AS base ARG VERSION RUN echo "Base image: $VERSION" FROM base RUN echo "Child image: $VERSION" #5 Base image: 123 #6 Child image: 123 1 2
я не хочу это знать! > new Date(0) Thu Jan 01 1970 03:00:00 GMT+0300 (Moscow Standard Time) new Date('0') Sat Jan 01 2000 00:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024-01-01') Mon Jan 01 2024 03:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024/01/01') Mon Jan 01 2024 00:00:00 GMT+0300 (Moscow Standard Time)
я не хочу это знать! > new Date(0) Thu Jan 01 1970 03:00:00 GMT+0300 (Moscow Standard Time) new Date('0') Sat Jan 01 2000 00:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024-01-01') Mon Jan 01 2024 03:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024/01/01') Mon Jan 01 2024 00:00:00 GMT+0300 (Moscow Standard Time)
я не хочу это знать! > new Date(0) Thu Jan 01 1970 03:00:00 GMT+0300 (Moscow Standard Time) new Date('0') Sat Jan 01 2000 00:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024-01-01') Mon Jan 01 2024 03:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024/01/01') Mon Jan 01 2024 00:00:00 GMT+0300 (Moscow Standard Time)
я не хочу это знать! > new Date(0) Thu Jan 01 1970 03:00:00 GMT+0300 (Moscow Standard Time) new Date('0') Sat Jan 01 2000 00:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024-01-01') Mon Jan 01 2024 03:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024/01/01') Mon Jan 01 2024 00:00:00 GMT+0300 (Moscow Standard Time)
я не хочу это знать! > new Date(0) Thu Jan 01 1970 03:00:00 GMT+0300 (Moscow Standard Time) new Date('0') Sat Jan 01 2000 00:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024-01-01') Mon Jan 01 2024 03:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024/01/01') Mon Jan 01 2024 00:00:00 GMT+0300 (Moscow Standard Time)
я не хочу это знать! > new Date(0) Thu Jan 01 1970 03:00:00 GMT+0300 (Moscow Standard Time) new Date('0') Sat Jan 01 2000 00:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024-01-01') Mon Jan 01 2024 03:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024/01/01') Mon Jan 01 2024 00:00:00 GMT+0300 (Moscow Standard Time)
я не хочу это знать! > new Date(0) Thu Jan 01 1970 03:00:00 GMT+0300 (Moscow Standard Time) new Date('0') Sat Jan 01 2000 00:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024-01-01') Mon Jan 01 2024 03:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024/01/01') Mon Jan 01 2024 00:00:00 GMT+0300 (Moscow Standard Time)
я не хочу это знать! > new Date(0) Thu Jan 01 1970 03:00:00 GMT+0300 (Moscow Standard Time) new Date('0') Sat Jan 01 2000 00:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024-01-01') Mon Jan 01 2024 03:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024/01/01') Mon Jan 01 2024 00:00:00 GMT+0300 (Moscow Standard Time)
я не хочу это знать! > new Date(0) Thu Jan 01 1970 03:00:00 GMT+0300 (Moscow Standard Time) new Date('0') Sat Jan 01 2000 00:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024-01-01') Mon Jan 01 2024 03:00:00 GMT+0300 (Moscow Standard Time) > new Date('2024/01/01') Mon Jan 01 2024 00:00:00 GMT+0300 (Moscow Standard Time)
простой и логичный! {'a': 1} # это словарь dict(a=1) # это то же самое {'a'} # это множество (set) {} # это не пустое множество, это пустой словарь set() # а вот это пустое множество
простой и логичный! {'a': 1} # это словарь dict(a=1) # это то же самое {'a'} # это множество (set) {} # это не пустое множество, это пустой словарь set() # а вот это пустое множество
простой и логичный! {'a': 1} # это словарь dict(a=1) # это то же самое {'a'} # это множество (set) {} # это не пустое множество, это пустой словарь set() # а вот это пустое множество
простой и логичный! {'a': 1} # это словарь dict(a=1) # это то же самое {'a'} # это множество (set) {} # это не пустое множество, это пустой словарь set() # а вот это пустое множество
простой и логичный! {'a': 1} # это словарь dict(a=1) # это то же самое {'a'} # это множество (set) {} # это не пустое множество, это пустой словарь set() # а вот это пустое множество
простой и логичный! {'a': 1} # это словарь dict(a=1) # это то же самое {'a'} # это множество (set) {} # это не пустое множество, это пустой словарь set() # а вот это пустое множество
простой и логичный! {'a': 1} # это словарь dict(a=1) # это то же самое {'a'} # это множество (set) {} # это не пустое множество, это пустой словарь set() # а вот это пустое множество
простой и логичный! {'a': 1} # это словарь dict(a=1) # это то же самое {'a'} # это множество (set) {} # это не пустое множество, это пустой словарь set() # а вот это пустое множество
простой и логичный! {'a': 1} # это словарь dict(a=1) # это то же самое {'a'} # это множество (set) {} # это не пустое множество, это пустой словарь set() # а вот это пустое множество
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! 1 # это просто число (int) (1+2) # это число (1, 2) # это кортеж (tuple) (1) # это тоже просто число 1, # это тоже кортеж () # это пустой кортеж (,) # SyntaxError
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это (ха-ха) кортеж (i for i in range(3)) # это не кортеж, это генератор :D
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это (ха-ха) кортеж (i for i in range(3)) # это не кортеж, это генератор :D
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это (ха-ха) кортеж (i for i in range(3)) # это не кортеж, это генератор :D
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это (ха-ха) кортеж (i for i in range(3)) # это не кортеж, это генератор :D
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это (ха-ха) кортеж (i for i in range(3)) # это не кортеж, это генератор :D
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это (ха-ха) кортеж (i for i in range(3)) # это не кортеж, это генератор :D
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это (ха-ха) кортеж (i for i in range(3)) # это не кортеж, это генератор :D
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это (ха-ха) кортеж (i for i in range(3)) # это не кортеж, это генератор :D
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это (ха-ха) кортеж (i for i in range(3)) # это не кортеж, это генератор :D
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это (ха-ха) кортеж (i for i in range(3)) # это не кортеж, это генератор :D
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это кортеж (i for i in range(3)) # это не кортеж, это генератор :D
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это кортеж (i for i in range(3)) # это не кортеж, это генератор
простой и логичный! [] # это пустой список [1] # это список с одним элементом [1, 2, 3] # это список с 3 элементами [i for i in range(3)] # это тоже список с 3 элементами () # это пустой кортеж (1) # это просто число (1, 2, 3) # это кортеж (i for i in range(3)) # это не кортеж, это генератор
потенциально опасные места и не даёт нам делать плохие вещи data = {1: 2} for key, value in data.items(): data[key+1] = value+1 RuntimeError: dictionary changed size during iteration data = [1, 2] for value in data: data.append(value+1) Всё ок! Прощай, RAM :)
потенциально опасные места и не даёт нам делать плохие вещи data = {1: 2} for key, value in data.items(): data[key+1] = value+1 RuntimeError: dictionary changed size during iteration data = [1, 2] for value in data: data.append(value+1) Всё ок! Прощай, RAM :)
потенциально опасные места и не даёт нам делать плохие вещи data = {1: 2} for key, value in data.items(): data[key+1] = value+1 RuntimeError: dictionary changed size during iteration data = [1, 2] for value in data: data.append(value+1) Всё ок! Прощай, RAM :)
потенциально опасные места и не даёт нам делать плохие вещи data = {1: 2} for key, value in data.items(): data[key+1] = value+1 RuntimeError: dictionary changed size during iteration data = [1, 2] for value in data: data.append(value+1) Всё ок! Прощай, RAM :)
__pycache__/ shell.py tests/ tools.py utils.py > pdm run pytest . ERROR collecting src/tests/test_bot.py ImportError while importing test module '/home/user/workspace/project/src/tests/test_bot.py'. Hint: make sure your test modules/packages have valid Python names. Traceback: .pyenv/versions/3.11.4/lib/python3.11/importlib/__init__.py:126: in import_module return _bootstrap._gcd_import(name[level:], package, level) tests/test_bot.py:3: in <module> from ..bot import message_handler E ImportError: attempted relative import beyond top-level package
SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config( 'search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; ...
из бэкапа: psql postgres < dump.sql -- dump.sql SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config( 'search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; ...
parse_partial_json) -> dict: """ Parse a JSON string from a Markdown string. Args: json_string: The Markdown string. Returns: The parsed JSON object as a Python dictionary. """
убиваю, чтобы понять, зачем делать слайс и менять в нём только первый элемент • Так нихрена и не понял • Ладно, читаю дальше const [squares, setSquares] = useState(Array(9).fill(null)); function handleClick() { const nextSquares = squares.slice(); nextSquares[0] = "X"; setSquares(nextSquares); } X
only to the upper left square. Your `handleClick` function is hardcoded to update the index for the upper left square (`0`). Let’s update `handleClick` to be able to update any square.” const [squares, setSquares] = useState(Array(9).fill(null)); function handleClick() { const nextSquares = squares.slice(); nextSquares[0] = "X"; setSquares(nextSquares); } X
с выпивкой • Никого нет • Приходят какие-то девушки • Я им затираю про питон, они ничего не понимают • Проверяю календарь • Я перепутал даты и пришёл ровно на неделю раньше