Яндекс практикум 13 урок где ошибка

У меня есть по вопрос по поводу 5-го курса 19 урока.
Условие: Теперь приведём функцию makeColorString(r,g,b) в рабочее состояние. Нужно в теле функции заменить все имена переменных red, green и blue на параметры r, g и b соответственно.
При проверке этого кода выводится ошибка и сообщение:
«Необходимо заменить имя переменной red на r внутри makeColorString().»
Укажите пожалуйста где здесь ошибка.

checkInput(red);
checkInput(green);
checkInput(blue);
function makeColorString(r, g, b) {
// red
if (isNaN(red)) {
  red = prompt('В качестве значения насыщенности красного вы ввели не число. Пожалуйста, введите число от 0 до 255.', '255');
} 
else if (red < 0) { 
  console.log("Наименьшее из возможных чисел — ноль, мы подставили значение 0.");
} 
else if (red > 255) {  
  console.log('Наибольшее возможное число — 255, мы подставили его.');
} 
else{
  red = console.log('Вы определили насыщенность красного как ' + red) 
}
console.log(isNaN(red));
  
}
var red, green, blue;
var bgValue = 'rgb(' + red + ', ' + green + ', ' + blue + ')';
console.log(bgValue);
var red = prompt ('Введите насыщенность красного в виде числа от 0 до 255', '255');
var green = prompt ('Введите насыщенность зелёного в виде числа от 0 до 255', '0');
var blue = prompt ('Введите насыщенность синего в виде числа от 0 до 255','0');
var red = NaN
makeColorString();
// CheckInput
function checkInput(i){
  i = Number(i);
if (isNaN(i)) {
  i = prompt('В качестве значения насыщенности цвета вы ввели не число. Пожалуйста, введите число от 0 до 255.', '255');
  i = Number(i);
} 
else if (i < 0) {  
  i = 0;
  console.log("Наименьшее из возможных чисел — ноль, мы подставили значение 0.");
} 
else if (i > 255) {  
  i = 255;
  console.log('Наибольшее возможное число — 255, мы подставили его.'); }
}

Если в makeColorString(); добавить хотя бы одну r, то всё-равно выводится ошибка (та же самая).

Или как мы потеряли 120 000 рублей (60 000 каждый) на обучении.

Update 1:

Мы созвонились с Дианой, из команды Практикума.
В звонке нам удалось во всем разобраться и решить вопрос. Хочется поблагодарить всех людей, которые помогли нам в этой проблеме! Ребята, вы — сила 💪
В ближайшее время мы, наконец, получим дипломы. Когда это случится, сообщу в следующем апдейте.
Также нам предложили скидку 50% на два курса или 100% на один. Выбрали второе (для жены). Если в этот раз курс пройдет успешно и Яндекс действительно сделал работу над ошибками, то ждите похвальную статью уже от жены 💕

Вступление. Немного о нас.

В конце прошлого года я со своей девушкой, а ныне женой, приняли решение пройти курсы тестировщика на Яндекс.Практикум. Долго сомневались, стоит ли, хватит ли у нас терпения и не окажется ли всё это тратой денег. Спойлер: оказалось.

Учились мы на одном потоке примерно полгода. По началу было просто — всё как по маслу, и даже нравилось. Курсы с 3 по 6 (6 курс — диплом) уже тяжеловато, так как совмещали работу и учёбу. Работаем мы в одной крупной компании техническими специалистами, и, конечно же, хотим двигаться дальше. Начитавших хваленых отзывов в интернете и по советам коллег двинулись в Практикум на тестировщика.

Формат учёбы

Учёба происходила в формате спринтов с мягким и жестким дедлайном. Нам предоставили доступ в Slack, где распределили в группу с куратором и парой наставников.

Всю учёбу можно поделить на 3 блока:

  • Тренажер — он же портал Яндекс.Практикум.
  • Slack — с наставниками, вебинарами и флудилкой.
  • Ревьюверы — с которыми особо нет взаимодействий (помимо проектов), но они играют ключевую роль.

Тренажер

Практикум пытается уместить большой объем информации в максимально сжатом виде. Причиной служит малое количество времени на обучение. Тебя постоянно подгоняют дедлайном, обосновывая это тем, что на работе так же.

Сам тренажер работает с ошибками. Студенты даже шутили на эту тему, мол, дополнительная проверка на тестировщика. Проблема с тренажером особо ощущается под конец курсов. Идеально написанный код может сработать только после обновления страницы. В некоторых случаях необходимо поставить/убрать символ там, где это не требуется в задании. Тогда всё заработает.

Старые разделы в тренажере могут обновить прямо в процессе обучения. Чаще всего это выходит боком, создавая путаницу. Быстро вернуться к пройденной теме не получится.

Slack

Толку от наставников было весьма мало, так как к вебинару они приходили чаще всего не подготовленными. Как оказалось, по причине наличия другой «основной» работы. На вопросы в группе Slack тебе отвечали в течение дня — и это в лучшем случае, иногда вообще забывали ответить.

Ревьюверы

Основная боль. Бардак и хаос.

Да, можно стерпеть сжатый тренажер с багами, редко отвечающих наставников с не информативными вебинарами. Но тебе нужно закрыть спринт, а для этого отправить работу на проверку ревьюверу. Напрямую общаться с ревьюверами не дают, что вызывает боль и недопонимание. Видимо из-за того, что они и так завалены работами (экономия на сотрудниках от Яндекса).

Время на проверку у ревьювера: ~96 часов, которое почти регулярно нарушается. Ревьюверы разные: один может не заметить ошибку в работе, а другой попросить сделать как-то иначе. В нашем потоке ревьюверы требовали от тебя того, что даже не было в тренажере или вебинаре. Опять обоснования: «А что вы хотели? Так есть и на реальной работе. Заказчик может потребовать выполнить работу другим образом». Мы поняли, это удобная отговорка от не налаженного процесса между разными отделами.

Финальная часть. Диплом.

Тотально выгоревшие. С горем пополам дошли до диплома. Их было два: первый и второй (альтернативный), но об этом чуть позже. Главная наша ошибка — мучить себя в ужасных условиях и не уйти раньше, когда была такая возможность. Этот урок был выучен на отлично.

Никаких индивидуальных созвонов с наставниками, адекватного обсуждения дипломного проекта нет и в помине. Выдали задание — разбирайтесь сами. Исходя из флудилки, даже у студентов-отличников, которые раньше щёлкали спринты как орешки, не было мотивации разбираться во всем этом месиве.

Первую дипломную работу проверяли долго. ОЧЕНЬ. ДОЛГО. Нервы у жены не выдержали, поэтому она написала в паблик потока. Куратор ответил в ЛС. Прикладываю скриншоты переписки (хорошо, что сохранили, ибо аккаунты в Slack уже удалены).

Куратор сливает работу ЧУЖОГО студента. Практически полностью готовый диплом. Спустя пару дней нам приходит ответ, что мы списали работу друг у друга 🤦‍♂

Скажу честно, первый дипломный проект другу друга и чужого (слитого) студента мы посмотрели, но выполняли всё самостоятельно.

Мы были в стрессе и на нервах. Нам предлагали либо уйти, либо остаться на второй (альтернативный) диплом. Выбрали второе. Ситуация повторилась, но на этот раз чужие работы мы не видели. Чуть ниже скриншот от поддержки, затем идут наши ответы.

Какие доводы приводит Практикум.

Мой ответ был тотально проигнорирован и на просьбу детально предоставить доказательства — игнор.

Жалоба на почту Практикум не привела к результату.

Ответ от жены был также проигнорирован.

Альтернативный диплом был выполнен самостоятельно. Это касается меня и моей жены. Мы в глаза не видели работы друг друга.

Увы, потраченное время и нервные клетки уже не вернуть.

TL;DR

Я с женой заплатили за курсы тестировщика в Яндекс.Практикум 120 тысяч рублей (60 каждый). Учёба была на отвратительном уровне, но мы продолжали учиться. Куратор слил работу другого студента. После сдачи дипломного проекта меня и мою жену обвинили в списывании (дважды). На просьбу детально предоставить доказательства и пересмотреть дело — игнор. Нас отчислили без возврата денег.

Задача 1

Напишите функцию what_weather() (англ. «какая погода?»), которую затем будете использовать в коде Анфисы:

  • Выполните HTTP-запрос, поместив вызов функции get() внутрь блока try.
  • Значения URL и параметров получите из функций make_url() (в неё нужно передать нужный город как аргумент city) и make_parameters().
  • При «выбрасывании» исключения типа requests.ConnectionError (от англ. «ошибка соединения») — функция what_weather() должна возвращать сообщение об ошибке '<сетевая ошибка>'.
  • Если код HTTP-ответа равен 200 (всё хорошо), верните из функции текст ответа. В противном случае функция должна вернуть строку '<ошибка на сервере погоды>'.

Код:

import requests

cities = [
    'Омск',
    'Калининград',
    'Челябинск',
    'Владивосток',
    'Красноярск',
    'Москва',
    'Екатеринбург'
]

def make_url(city):
    # в URL задаём город, в котором узнаем погоду
    return f'http://wttr.in/{city}'

def make_parameters():
    params = {
        'format': 2,  # погода одной строкой
        'M': ''  # скорость ветра в "м/с"
    }
    return params

def what_weather(city):
    # Напишите тело этой функции.
    # Не изменяйте остальной код!
    try:
        request = requests.get(make_url(city), params=make_parameters())
        #print(request.status_code)
        if request.status_code == 200: return request.text
        else: return '<ошибка на сервере погоды>'
    except requests.ConnectionError : return '<сетевая ошибка>'

print('Погода в городах:')
for city in cities:
    print(city, what_weather(city))

Результат:

Погода в городах:
Омск ? ?️-7°C ?️↖4.2 m/s

Калининград ⛅️ ?️+2°C ?️↖6.1 m/s

Челябинск ? ?️-3°C ?️↘6.1 m/s

Владивосток ☀️ ?️-3°C ?️↓7.2 m/s

Красноярск ⛅️ ?️-10°C ?️→8.3 m/s

Москва ☀️ ?️-2°C ?️↑4.2 m/s

Екатеринбург ? ?️-2°C ?️↘4.2 m/s

Задача 2

Это задание — финальное.

В нём вы сделаете Анфису мастером на все руки.

Анфиса будет знать всё про ваших друзей — где они, сколько у них времени, и какая у них погода.В список запросов queries в функции runner() добавлены новые запросы про погоду:

  • Коля, как погода?
  • Соня, как погода?
  • Антон, как погода?

Научите Анфису отвечать на вопросы такого вида.

Для этого:

  1. Добавьте в функцию process_friend() обработку ещё одного запроса 'как погода?'. Для получения ответа на этот вопрос используйте значение city — это город, в котором живёт друг.
  2. Затем вызовите функцию what_weather() — вы написали на прошлом уроке почти такую же. Она уже доступна в коде этого задания.
  3. Верните результат выполнения этой функции как результат process_friend().

Код:

import datetime as dt
import requests

DATABASE = {
    'Сергей': 'Омск',
    'Соня': 'Москва',
    'Алексей': 'Калининград',
    'Миша': 'Москва',
    'Дима': 'Челябинск',
    'Алина': 'Красноярск',
    'Егор': 'Пермь',
    'Коля': 'Красноярск',
    'Артём': 'Владивосток',
    'Петя': 'Михайловка'
}

UTC_OFFSET = {
    'Москва': 3,
    'Санкт-Петербург': 3,
    'Новосибирск': 7,
    'Екатеринбург': 5,
    'Нижний Новгород': 3,
    'Казань': 3,
    'Челябинск': 5,
    'Омск': 6,
    'Самара': 4,
    'Ростов-на-Дону': 3,
    'Уфа': 5,
    'Красноярск': 7,
    'Воронеж': 3,
    'Пермь': 5,
    'Волгоград': 4,
    'Краснодар': 3,
    'Калининград': 2,
    'Владивосток': 10
}


def format_count_friends(count_friends):
    if count_friends == 1:
        return '1 друг'
    elif 2 <= count_friends <= 4:
        return f'{count_friends} друга'
    else:
        return f'{count_friends} друзей'


def what_time(city):
    offset = UTC_OFFSET[city]
    city_time = dt.datetime.utcnow() + dt.timedelta(hours=offset)
    f_time = city_time.strftime("%H:%M")
    return f_time


def what_weather(city):
    url = f'http://wttr.in/{city}'
    weather_parameters = {
        'format': 2,
        'M': ''
    }
    try:
        response = requests.get(url, params=weather_parameters)
    except requests.ConnectionError:
        return '<сетевая ошибка>'
    if response.status_code == 200:
        return response.text.strip()
    else:
        return '<ошибка на сервере погоды>'


def process_anfisa(query):
    if query == 'сколько у меня друзей?':
        count_string = format_count_friends(len(DATABASE))
        return f'У тебя {count_string}'
    elif query == 'кто все мои друзья?':
        friends_string = ', '.join(DATABASE.keys())
        return f'Твои друзья: {friends_string}'
    elif query == 'где все мои друзья?':
        unique_cities = set(DATABASE.values())
        cities_string = ', '.join(unique_cities)
        return f'Твои друзья в городах: {cities_string}'
    else:
        return '<неизвестный запрос>'


def process_friend(name, query):
    if name in DATABASE:
        city = DATABASE[name]
        if query == 'ты где?':
            return f'{name} в городе {city}'
        elif query == 'который час?':
            if city not in UTC_OFFSET:
                return f'<не могу определить время в городе {city}>'
            time = what_time(city)
            return f'Там сейчас {time}'
        elif query == 'как погода?':
            return what_weather(city)
            
        else:
            return '<неизвестный запрос>'
    else:
        return f'У тебя нет друга по имени {name}'


def process_query(query):
    tokens = query.split(', ')
    name = tokens[0]
    if name == 'Анфиса':
        return process_anfisa(tokens[1])
    else:
        return process_friend(name, tokens[1])


def runner():
    queries = [
        'Анфиса, сколько у меня друзей?',
        'Анфиса, кто все мои друзья?',
        'Анфиса, где все мои друзья?',
        'Анфиса, кто виноват?',
        'Коля, ты где?',
        'Соня, что делать?',
        'Антон, ты где?',
        'Алексей, который час?',
        'Артём, который час?',
        'Антон, который час?',
        'Петя, который час?',
        'Коля, как погода?',
        'Соня, как погода?',
        'Антон, как погода?'
    ]
    for query in queries:
        print(query, '-', process_query(query))


runner()

Результат:

Анфиса, сколько у меня друзей? - У тебя 10 друзей
Анфиса, кто все мои друзья? - Твои друзья: Сергей, Соня, Алексей, Миша, Дима, Алина, Егор, Коля, Артём, Петя
Анфиса, где все мои друзья? - Твои друзья в городах: Омск, Калининград, Михайловка, Красноярск, Москва, Челябинск, Владивосток, Пермь
Анфиса, кто виноват? - <неизвестный запрос>
Коля, ты где? - Коля в городе Красноярск
Соня, что делать? - <неизвестный запрос>
Антон, ты где? - У тебя нет друга по имени Антон
Алексей, который час? - Там сейчас 15:50
Артём, который час? - Там сейчас 23:50
Антон, который час? - У тебя нет друга по имени Антон
Петя, который час? - <не могу определить время в городе Михайловка>
Коля, как погода? - ⛅️ ?️-10°C ?️→7.2 m/s
Соня, как погода? - ☀️ ?️-3°C ?️↑4.2 m/s
Антон, как погода? - У тебя нет друга по имени Антон

Сегодня говорим про обработку ошибок и отказоустойчивость программ. Это продолжение статьи про исключения, но применительно к нашему проекту под кодовым названием «Воруй, убивай, цепи Маркова». Мы учимся забирать текст с чужих сайтов и генерировать на основе этого текста собственные. 

В предыдущих версиях у нас были идеальные условия: заготовленный список веб-страниц одинакового формата, с одинаковой кодировкой и одинаковой разметкой заголовков. 

В реальном парсинге условия неидеальные: чаще всего нужно парсить не свой сайт, а чужой. И на этом чужом сайте может быть что угодно: не открываются адреса, нет заголовка на странице, разные кодировки на разных страницах. Для компьютера это непреодолимые трудности. 

Чтобы такого не происходило, нам нужно научить наш алгоритм обрабатывать нештатные ситуации — то есть исключения. 

Что делаем

Идея для сегодняшнего проекта — спарсить часть текста и заголовков с сайта «Коммерсанта» для учебных целей. Потом мы их отдадим нашему алгоритму на цепях Маркова и получим новые тексты в духе «Коммерсанта».

Мы выбрали «Коммерсант» из-за его удобной структуры URL-адреса. Вот как выглядят типичные адреса новостей оттуда:

https://www.kommersant.ru/doc/4815427

https://www.kommersant.ru/doc/4803922

Видно, что каждая новость или статья просто опубликована под каким-то своим номером и есть ощущение, что эти номера идут по порядку. Поэтому сделаем так:

  1. Выберем стартовый номер у новости.
  2. Будем отнимать от этого номера единичку, подставлять его в адрес и смотреть на результат.
  3. Если страница откроется, сохраним заголовок и текст новости, а если нет — пойдём дальше.
  4. Повторим это 500 раз и посмотрим, что получится.

Адаптируем старый проект под новую задачу

Чтобы не писать всё с нуля, мы возьмём наш парсер из прошлого проекта и выкинем оттуда громадный кусок с массивом URL-адресов.

# подключаем urlopen из модуля urllib
from urllib.request import urlopen

# подключаем библиотеку BeautifulSout
from bs4 import BeautifulSoup

# открываем текстовый файл, куда будем добавлять заголовки
file = open("zag.txt", "a")

# перебираем все адреса из списка
for x in url:
    # получаем исходный код очередной страницы из списка
    html_code = str(urlopen(x).read(),'utf-8')
    # отправляем исходный код страницы на обработку в библиотеку
    soup = BeautifulSoup(html_code, "html.parser")

    # находим название страницы с помощью метода find()
    s = soup.find('title').text

    # выводим его на экран
    print(s)

    # сохраняем заголовок в файле и переносим курсор на новую строку
    file.write(s + '. ')

# закрываем файл
file.close()

Теперь добавим в этот код нашу логику. Для этого мы пропишем общую часть URL-адреса, запомним стартовый номер новости, а потом в цикле будем вычитать из него единичку и смотреть, что получилось.

👉 Мы вычитаем единицы из стартового числа, чтобы получить доступ к предыдущим материалам, потому что у новых статей номер в адресе «Коммерсанта» всегда больше, чем у старых. Ещё мы теперь ищем заголовок самой новости, а не всей страницы, потому что в заголовке страницы много лишнего текста.

# подключаем urlopen из модуля urllib
from urllib.request import urlopen

# подключаем библиотеку BeautifulSout
from bs4 import BeautifulSoup

# общая часть URL-адреса
url = "https://www.kommersant.ru/doc/"
# стартовый номер, с которого начинаем парсинг
start_id = 4804129

# открываем  файл, куда будем добавлять заголовки
file_zag = open("komm_zag.txt", "a")
# открываем  файл, куда будем добавлять текст
file_text = open('komm_text.txt','a')

# перебираем предыдущие 500 адресов
for x in range(0,500):

    # формируем новый адрес из общей части и номера материала
    # на каждом шаге номер уменьшается на единицу, чтобы обратиться к более старым материалам
    work_url = url + str(start_id - x)

    # получаем исходный код очередной страницы из списка
    html_code = str(urlopen(work_url).read(),'utf-8')
    # отправляем исходный код страницы на обработку в библиотеку
    soup = BeautifulSoup(html_code, "html.parser")

    # находим заголовок материала с помощью метода find()
    s = soup.find('h1').text
    # выводим его на экран
    print(s)

    # сохраняем заголовок в файле и переносим курсор на новую строку
    file_zag.write(s + '. ')

    # находим все абзацы с текстом
    content = soup.find_all('p')
    # перебираем все найденные абзацы
    for item in content:
        # сохраняем каждый абзац в другой файл
        file_text.write(item.text + ' ')
        print(item.text)

# закрываем файл
file.close()

После запуска мы видим две проблемы. Первая: у нас собирается много лишних абзацев с текстом, который не относится к новости. Все эти «Читать далее», «Архив» и «просмотров» нам не нужны:

Простая работа с исключениями

Вторая проблема: оказывается, не на всех страницах наш парсер может найти заголовок <h1>. Например, такое случается, если по текущему адресу материал доступен только по подписке или там находится служебная страница:

Простая работа с исключениями

Находим только текст новости

Чтобы не собирать со страницы все абзацы, а брать только нужный текст, давайте посмотрим на структуру любой подобной страницы в инспекторе:

Простая работа с исключениями

В коде видно, что содержимое статьи помечается абзацем с классом «b-article__text» , значит, нам нужно забирать со страницы только абзацы с таким классом. Поменяем нашу команду на такое:

content = soup.find_all('p', class_ = "b-article__text")

Теперь мы найдём на странице только те абзацы, у которых будет нужный нам класс, а остальные проигнорируем.

Добавляем исключение для обработки заголовков

👉 В этом проекте мы варварски отнеслись к исключениям и не проверяли тип ошибки, зато быстро получили рабочий код. В следующий раз мы исправимся, а пока будем работать на скорость.

Мы уже рассказывали про то, что такое исключения и как они помогают программистам. Если коротко, то исключения позволяют обработать заранее известную ошибку так, чтобы программа не прекращала работу, а продолжала делать что-то своё.

Мы будем использовать самый простой вариант обработки исключений: когда исключение обрабатывается в общем виде, без уточнения ошибки. Вот как это будет работать:

  1. Мы добавляем обработчик исключений к команде нахождения заголовка.
  2. Если всё нашлось нормально и ошибки нет, то обработчик будет сидеть тихо и ничего не делать.
  3. Если после команды поиска заголовка случилась ошибка, то мы сразу прекращаем дальнейшие команды и переходим к следующему адресу.

Плюсы такого решения — простота и скорость внедрения. Нам не нужно задумываться о том, какая именно ошибка случилась: при любой ошибке мы бросаем этот адрес и переходим к следующему.

Минус у этого способа тоже есть: мы не знаем, что именно произошло, и реагируем на всё одинаково. В простом учебном проекте это можно сделать, а в настоящем коммерческом коде — нет. Там нужно чётко всегда знать, что за ошибка случилась, чтобы проект более гибко и правильно реагировал на происходящее.

# включаем обработчик исключений для команды поиска
    try:
        # находим название страницы с помощью метода find()
        s = soup.find('h1').text
    # если случилась любая ошибка
    except Exception as e:
        print("Заголовок не найден")
        # прерываем этот шаг цикла и переходим к следующему
        continue

Обрабатываем ситуацию, когда страница не найдена

После того как мы исправили два предыдущих замечания и снова запустили программу, компьютер выдал ошибку 404 — страница с таким адресом не найдена:

Простая работа с исключениями

Это значит, что мы отправили запрос на такую страницу, которой нет на сервере. Так бывает, когда проверяешь адреса простым перебором — часть вариантов окажется нерабочими. 

Чтобы эта ошибка не мешала работать программе, снова добавим исключение с обработкой любой ошибки. Как только на этой команде встретили ошибку, то делаем как и раньше — бросаем всё и начинаем цикл с нового адреса.

# включаем обработчик исключений для запроса содержимого страницы
    try:
        # получаем исходный код страницы в виде байт-строки
        html_code = urlopen(work_url).read()
    # если случилась любая ошибка
    except Exception as e:
        print('Страница не найдена')
        # прерываем этот шаг цикла и переходим к следующему
        continue

Так, шаг за шагом, мы отлавливаем все ошибки и получаем код, который сможет обработать хоть 50 000 страниц и не упасть во время работы. В этом и есть смысл исключений — сделать так, чтобы программа продолжала работать, когда что-то пошло не по плану. Главное — предусмотреть возможные нештатные ситуации.

# подключаем urlopen из модуля urllib
from urllib.request import urlopen

# подключаем библиотеку BeautifulSout
from bs4 import BeautifulSoup

# общая часть URL-адреса
url = "https://www.kommersant.ru/doc/"
# стартовый номер, с которого начинаем парсинг
start_id = 4804129

# открываем  файл, куда будем добавлять заголовки
file_zag = open("komm_zag.txt", "a")
# открываем  файл, куда будем добавлять текст
file_text = open('komm_text.txt','a')

# перебираем предыдущие 500 адресов
for x in range(0,500):

    # формируем новый адрес из общей части и номера материала
    # на каждом шаге номер уменьшается на единицу, чтобы обратиться к более старым материалам
    work_url = url + str(start_id - x)

    # включаем обработчик исключений для запроса содержимого страницы
    try:
        # получаем исходный код страницы в виде байт-строки
        html_code = urlopen(work_url).read()
    # если случилась любая ошибка
    except Exception as e:
        print('Страница не найдена')
        # прерываем этот шаг цикла и переходим к следующему
        continue

    # отправляем исходный код страницы на обработку в библиотеку
    soup = BeautifulSoup(html_code, "html.parser")

    # включаем обработчик исключений для команды поиска
    try:
        # находим название страницы с помощью метода find()
        s = soup.find('h1').text
    # если случилась любая ошибка
    except Exception as e:
        print("Заголовок не найден")
        # прерываем этот шаг цикла и переходим к следующему
        continue
    # выводим его на экран
    print(s)

    # сохраняем заголовок в файле и переносим курсор на новую строку
    file_zag.write(s + '. ')

    # находим все абзацы с текстом новости
    content = soup.find_all('p', class_ = "b-article__text")
    # перебираем все найденные абзацы
    for item in content:
        # сохраняем каждый абзац в другой файл
        file_text.write(item.text + ' ')
        print(item.text)

# закрываем файл
file.close()

Что дальше

У нас есть 500 заголовков и столько же новостей — можно собрать новости в стиле «Коммерсанта». Если не знаете, как это сделать, — почитайте нашу статью про генератор на цепях Маркова

Здравствуйте все! Прохожу бесплатный курс на Яндекс Практикуме по Питону и застрял на одной задаче. Прошу не пугаться, что ниже такой длинный код, на самом деле тут всё просто, изменения нужны небольшие, только я уже 2 часа не могу понять, почему код не работает )). Просмотрел уже не один раз, ну ведь должен он работать )).

В общем суть в том, что программа должна выдать такой результат:

Анфиса, сколько у меня друзей? — У тебя 7 друзей
Анфиса, кто все мои друзья? — Твои друзья: Сергей, Соня, Миша, Дима, Алина, Егор, Коля
Анфиса, где все мои друзья? — Твои друзья в городах: Омск, Москва, Красноярск, Пермь, Челябинск
Анфиса, кто виноват? — <неизвестный запрос>
Коля, ты где? — Коля в городе Красноярск
Соня, что делать? — <неизвестный запрос>
Антон, ты где? — У тебя нет друга по имени Антон

Уберу в спойлер формулировку задания:

2.
А. Напишите функцию process_friend(name, query), принимающую имя друга name и запрос query.

  • Если друга с указанным именем ‘Н’ нет в списке, то функция должна вернуть сообщение об ошибке У тебя нет друга по имени Н.
  • Если запрос — «ты где?», то функция должна вернуть сообщения ‘Н в городе Г’, где Г определяется по данным словаря DATABASE.
  • Если запрос не «ты где?», а какой-то другой, то функция должна вернуть сообщение об ошибке <неизвестный запрос>.

Б. Допишите функцию process_query(). Если запрос начинается не с «Анфиса», а с другого имени, то вызовите функцию process_friend(name, query), передав в неё имя друга и тело запроса. И верните результат выполнения этой функции.
В. Добавьте в список queries новые запросы вида:

  • Коля, ты где?
  • Соня, что делать?
  • Антон, ты где?

Что-то неправильно написано в функции process_friend или в функции process_query. У меня получается такой результат (последние строки почему-то выводятся все в одну строку):

Анфиса, сколько у меня друзей? — У тебя 7 друзей
Анфиса, кто все мои друзья? — Твои друзья: Сергей, Соня, Миша, Дима, Алина, Егор, Коля
Анфиса, где все мои друзья? — Твои друзья в городах: Омск, Москва, Красноярск, Пермь, Челябинск
Анфиса, кто виноват?Коля, ты где?Соня, что делать?Антон, ты где? — <неизвестный запрос>

А вот код:

Python:

DATABASE = {
    'Сергей': 'Омск',
    'Соня': 'Москва',
    'Миша': 'Москва',
    'Дима': 'Челябинск',
    'Алина': 'Красноярск',
    'Егор': 'Пермь',
    'Коля': 'Красноярск'
}


def format_count_friends(count_friends):
    if count_friends == 1:
        return '1 друг'
    elif 2 <= count_friends <= 4:
        return f'{count_friends} друга'
    else:
        return f'{count_friends} друзей'


def process_anfisa(query):
    if query == 'сколько у меня друзей?' or query == 'колько у меня друзей?': # был какой-то глюк тренажера и пришлось добавить фразу 'колько у меня друзей?' 
        count_string = format_count_friends(len(DATABASE))
        return f'У тебя {count_string}'
    elif query == 'кто все мои друзья?':
        friends_string = ', '.join(DATABASE.keys())
        return f'Твои друзья: {friends_string}'
    elif query == 'где все мои друзья?':
        unique_cities = set(DATABASE.values())
        cities_string = ', '.join(unique_cities)
        return f'Твои друзья в городах: {cities_string}'
    else:
        return '<неизвестный запрос>'

    
def process_query(query):
    tokens = query.split(', ')
    name = tokens[0]
    if name == 'Анфиса':
        query = query.strip('Анфиса, ')
        return process_anfisa(query)
    else:
        query = query.strip('Коля, ')
        return process_friend(name, query)
        
def process_friend(name, query):
    if name in DATABASE:
        if query == 'ты где?':
            city = DATABASE[name]
            return f'{name} в городе {city}'
        else:
            return '<неизвестный запрос>'
    else:
        return f'У тебя нет друга по имени {name}'
    
        
def runner():
    queries = [
        'Анфиса, сколько у меня друзей?',
        'Анфиса, кто все мои друзья?',
        'Анфиса, где все мои друзья?',
        'Анфиса, кто виноват?'
        'Коля, ты где?'
        'Соня, что делать?'
        'Антон, ты где?'
    ]
    
    for query in queries:
        print(query + ' - ' + process_query(query))


runner()

Или как мы потеряли 120 000 рублей (60 000 каждый) на обучении.

Update 1:

Мы созвонились с Дианой, из команды Практикума.
В звонке нам удалось во всем разобраться и решить вопрос. Хочется поблагодарить всех людей, которые помогли нам в этой проблеме! Ребята, вы — сила 💪
В ближайшее время мы, наконец, получим дипломы. Когда это случится, сообщу в следующем апдейте.
Также нам предложили скидку 50% на два курса или 100% на один. Выбрали второе (для жены). Если в этот раз курс пройдет успешно и Яндекс действительно сделал работу над ошибками, то ждите похвальную статью уже от жены 💕

Вступление. Немного о нас.

В конце прошлого года я со своей девушкой, а ныне женой, приняли решение пройти курсы тестировщика на Яндекс.Практикум. Долго сомневались, стоит ли, хватит ли у нас терпения и не окажется ли всё это тратой денег. Спойлер: оказалось.

Учились мы на одном потоке примерно полгода. По началу было просто — всё как по маслу, и даже нравилось. Курсы с 3 по 6 (6 курс — диплом) уже тяжеловато, так как совмещали работу и учёбу. Работаем мы в одной крупной компании техническими специалистами, и, конечно же, хотим двигаться дальше. Начитавших хваленых отзывов в интернете и по советам коллег двинулись в Практикум на тестировщика.

Формат учёбы

Учёба происходила в формате спринтов с мягким и жестким дедлайном. Нам предоставили доступ в Slack, где распределили в группу с куратором и парой наставников.

Всю учёбу можно поделить на 3 блока:

  • Тренажер — он же портал Яндекс.Практикум.
  • Slack — с наставниками, вебинарами и флудилкой.
  • Ревьюверы — с которыми особо нет взаимодействий (помимо проектов), но они играют ключевую роль.

Тренажер

Практикум пытается уместить большой объем информации в максимально сжатом виде. Причиной служит малое количество времени на обучение. Тебя постоянно подгоняют дедлайном, обосновывая это тем, что на работе так же.

Сам тренажер работает с ошибками. Студенты даже шутили на эту тему, мол, дополнительная проверка на тестировщика. Проблема с тренажером особо ощущается под конец курсов. Идеально написанный код может сработать только после обновления страницы. В некоторых случаях необходимо поставить/убрать символ там, где это не требуется в задании. Тогда всё заработает.

Старые разделы в тренажере могут обновить прямо в процессе обучения. Чаще всего это выходит боком, создавая путаницу. Быстро вернуться к пройденной теме не получится.

Slack

Толку от наставников было весьма мало, так как к вебинару они приходили чаще всего не подготовленными. Как оказалось, по причине наличия другой «основной» работы. На вопросы в группе Slack тебе отвечали в течение дня — и это в лучшем случае, иногда вообще забывали ответить.

Ревьюверы

Основная боль. Бардак и хаос.

Да, можно стерпеть сжатый тренажер с багами, редко отвечающих наставников с не информативными вебинарами. Но тебе нужно закрыть спринт, а для этого отправить работу на проверку ревьюверу. Напрямую общаться с ревьюверами не дают, что вызывает боль и недопонимание. Видимо из-за того, что они и так завалены работами (экономия на сотрудниках от Яндекса).

Время на проверку у ревьювера: ~96 часов, которое почти регулярно нарушается. Ревьюверы разные: один может не заметить ошибку в работе, а другой попросить сделать как-то иначе. В нашем потоке ревьюверы требовали от тебя того, что даже не было в тренажере или вебинаре. Опять обоснования: «А что вы хотели? Так есть и на реальной работе. Заказчик может потребовать выполнить работу другим образом». Мы поняли, это удобная отговорка от не налаженного процесса между разными отделами.

Финальная часть. Диплом.

Тотально выгоревшие. С горем пополам дошли до диплома. Их было два: первый и второй (альтернативный), но об этом чуть позже. Главная наша ошибка — мучить себя в ужасных условиях и не уйти раньше, когда была такая возможность. Этот урок был выучен на отлично.

Никаких индивидуальных созвонов с наставниками, адекватного обсуждения дипломного проекта нет и в помине. Выдали задание — разбирайтесь сами. Исходя из флудилки, даже у студентов-отличников, которые раньше щёлкали спринты как орешки, не было мотивации разбираться во всем этом месиве.

Первую дипломную работу проверяли долго. ОЧЕНЬ. ДОЛГО. Нервы у жены не выдержали, поэтому она написала в паблик потока. Куратор ответил в ЛС. Прикладываю скриншоты переписки (хорошо, что сохранили, ибо аккаунты в Slack уже удалены).

Куратор сливает работу ЧУЖОГО студента. Практически полностью готовый диплом. Спустя пару дней нам приходит ответ, что мы списали работу друг у друга 🤦‍♂

Скажу честно, первый дипломный проект другу друга и чужого (слитого) студента мы посмотрели, но выполняли всё самостоятельно.

Мы были в стрессе и на нервах. Нам предлагали либо уйти, либо остаться на второй (альтернативный) диплом. Выбрали второе. Ситуация повторилась, но на этот раз чужие работы мы не видели. Чуть ниже скриншот от поддержки, затем идут наши ответы.

Какие доводы приводит Практикум.

Мой ответ был тотально проигнорирован и на просьбу детально предоставить доказательства — игнор.

Жалоба на почту Практикум не привела к результату.
Ответ от жены был также проигнорирован.

Альтернативный диплом был выполнен самостоятельно. Это касается меня и моей жены. Мы в глаза не видели работы друг друга.

Увы, потраченное время и нервные клетки уже не вернуть.

TL;DR

Я с женой заплатили за курсы тестировщика в Яндекс.Практикум 120 тысяч рублей (60 каждый). Учёба была на отвратительном уровне, но мы продолжали учиться. Куратор слил работу другого студента. После сдачи дипломного проекта меня и мою жену обвинили в списывании (дважды). На просьбу детально предоставить доказательства и пересмотреть дело — игнор. Нас отчислили без возврата денег.

Предисловие

Недавно для себя открыл сервис Яндекса — Практикум. Мне очень понравилась идея, и я прошёл серию бесплатных уроков курса Python beckend-разработчик. Бесплатный курс называется «Основы Python»

Хоть я и не новичок в Python-е, но курс для меня оказался очень полезным. Он учит не только основам программированию, но и правильному подходу к работе для новичков.

У меня отец хотел научиться. Ему, между прочим, 75 лет. Он попробовал, но у него не получилось. Камнем преткновения оказалось развернуть и пользоваться у себя на компьютере какую-нибудь IDE. Он начал изучать по книжке, а в книжке ничего про это не было.

Ему просто хотелось попрактиковаться программированию, понять вообще что это такое, приобщиться к новому опыту. И самое главное, просто понять, что это за программирование такое. Я разбираться в новом и непонятном редакторе IDE ему не хотелось.

Я как только натолкнулся на этот практикум, сразу вспомнил про отца. Это действительно то, что нужно, чтобы вникнуть в суть программирования без лишних заморочек и просто понять, твоё это или нет.

На данный момент, отец прошёл несколько уроков и втянулся. Посмотрим, чем это всё закончится.

Что я хочу сделать

Курс Яндекса устроен таким образом, что тебя как будто берут стажёром в IT-компанию. Там тебе дают в разработку небольшой проект, и ты постепенно его разрабатываешь начиная с самых азов и довольно глубоко.

Всё это происходит онлайн и соответственно весь этот проект остаётся на серверах Яндекса. А мне хочется получить этот проект, сначала, локально, затем, с ним поэкспериментировать и, наконец, выложить на Github-е.

Установка Python, Django и IDE PyCharm

У меня стоит совершенно новая система UBUNTU MATE 20.04, и все установки и настройки буду описывать именно для неё.

Установка Python

На самом деле в Ubuntu 20.04 уже стоит Python 3.8.2 и его устанавливать не надо. Но в будущем потребуется устанавливать различные модули, а для этого нужен менеджер пакетов pip.

sudo apt-get install python3-pip

Указанная выше команда установит пакетный менеджер и Python теперь полностью готов для работы.

Установка Django

Проект курса Яндекса использует Framework Django, а значит установить его нужно обязательно.

Вообще, насколько мне известно, установить Django можно тремя разными способами: в проект, текущему пользователю и в систему.

При установке локальному пользователю, консольные команды Django не попадают в пути по умолчанию $PATH, и вызывать их приходиться прописывая полный путь: ‘~/.local/bin/django-admin.

Часто вызывать такую команду не очень удобно, поэтому я решил установить Django в систему:

sudo python3 -m pip install django --system

Установка PyCharm

Конечно PyCharm не единственная IDE для разработки на Python, но я к ней уже привык.

Установить бесплатную версию PyCharm можно командой:

sudo snap install pycharm-community --classic

При первом запуске PyCharm можно выбрать светлую или тёмную тему. Я выбираю тёмную тему.

Резюме

Подводя итоги, нам понадобилось всего три команды:

sudo apt-get install python3-pip # Установка # менеджера пакетов Питона sudo python3 -m pip install django --system # Установка Django sudo snap install pycharm-community --classic # Установка # PyCharm

Знакомство с Django

Знакомство с Django на курсе Яндекс начинается уже с подготовленного проекта.

Так обычно и бывает в жизни. Редко когда бывает, что ты устраиваешься на работу и сразу начинаешь новый проект. Ты, как правило, продолжаешь вести какой-то уже начатый другими проект.

Однако, мне нужно, чтобы всё заработало на моём локальном компьютере. А для этого нужно создать проект. Проект будет называться «Anfisa for Friends». Это аналог Алисы Яндекса.

Создание Python-проекта в PyCharm

Сперва наперво, мы создаём пустой проект со следующими установками:

Настройки проекта PyCharm

Создание Django-проекта

Теперь заходим в директорию нашего проекта и создаем каркас приложения на Django:

django-admin startproject anfisa4friends

В результате получаем структуру нового проекта:

Структура Django-проекта

Структура получилась не совсем такая, как в курсе Яндекса.

Во-первых, нужно было запустить ‘django-admin’ не в папке проекта, а в папке проектов. Я это переделаю.

Запуск Django-проекта

Остальными переделками я займусь позже, а сейчас нужно проверить работает ли Django. Для этого в папке проекта запускаем:

python3 manage.py runserver

Теперь нужно перейти в браузер и набрать в строке адреса: http://127.0.0.1:8000/.

Если всё работает, то в окне браузера должно появиться следующее:

Успешный запуск Django

Ура! Ура! Ура-а-а-а! Всё работает!

Резюме

Как выяснилось для работы с Django нет необходимости сначала создавать Python-проект.

Для знакомства с Django мы используем две команды:

django-admin startproject anfisa4friends # создание проекта python3 manage.py runserver # запуск проекта

Проверить работу сайта проекта можно по адресу: http://127.0.0.1:8000/

Все ошибки или предупреждения можно прочитать в терминале.

Следующая команда обновляет базу данных и все предупреждения исчезают.

python3 manage.py migrate # Обновление базы данных проекта

И так, у нас есть каркас Django-проекта, который работает, и что-то там печатает в окне браузера.

Знакомство с Git

Однако, нам хотелось бы, чтобы проект печатал не абы какой текст, а наш текст. К тому же в терминале, при запуске проекта, выскакивает предупреждение, суть которого в том, что проект может работать неправильно, до запуска python3 manage.py migrate.

Чтобы всё это исправить, нужно внести изменения. Самый простой способ это сделать — это удалить лишние файлы, а содержимой оставшихся файлов заменить содержимым файлов из курса Яндекс практикума.

Однако, в этом случае мы не поймём, какие изменения были сделаны и нечему не научимся. Нам необходимо сравнить файлы в нашем проекте с файлами в проекте Яндекса, а ключевые изменения понять и запомнить.

Для контроля всех изменений в проекте, и особенно изменений в файле с одинаковым названием, существует система контроля версий Git.

Установка Git

В моей версии Ubuntu Git не установлен по умолчанию. Установить Git можно следующей командой:

sudo apt install git # Установка утилиты Git

Создание git-репозитория

Для сравнения различных версий, нам нужно сохранить состояние До и состояние После. Все эти состояние проекта будут хранится в git-репозитории. Для его создания нужно в корне проекта запустить команду:

git init # Создания git-репозитория

Для того, чтобы убедиться, что репозиторий создан, и посмотреть его статус, существует специальная команда:

git status

Если репозиторий успешно создан, мы увидим следующий вывод в терминале:

Команда git status

Сообщение «Ещё нет коммитов» говорит о том, что в репозитории ещё ничего не сохранено. А красным выделены файлы и папки, которые могут быть сохранены.

Настройка git-репозитория

Для правильной работы git-репозитория требуются учётные данные. Они задаются следующими командами.

git config --global user.email "deviur@yandex.ru" git config --global user.name "Deviur"

Добавляем файл .gitignore

Если теперь запустить проект, то в проекте автоматически будут созданы две папки.

Какие файлы исключить с .gitignore

Эти папки нам не нужно сохранять в проект.

Для того чтобы исключить папки и файлы из проекта используется файл ‘.gitignore’. В этот файл записывается всё, что не нужно включать в проект.

.idea/ anfisa4friends/__pycache__/

Сохранение текущего состояния проекта

Прежде всего нам нужно выбрать какие файлы и папки добавить в репозиторий.

Чтобы добавить все доступные файлы используется следующая команда:

git add . # добавить файлы для сохранения в git-репозиторий

Теперь вывод `git status` показывает все изменения, которые произошли с файлами, которые мы добавили.

Результат команды git status

Как видно, коммитов ещё нет. Это значит текущее состояние мы ещё не сохранили. Мы только отметили, какие изменения и какие файлы сохранить.

Теперь сохраняем текущее состояние проекта в репозиторий:

git commit -m'Start Django-project'

Ура! Проект сохранён в git-репозитории. Теперь он имеет следующую структуру.

k

Резюме

Для начала работы с Git и сохранения нашего проекта мы использовали следующие команды:

sudo apt install git # установка Git git init # создание git-репозитория git status # проверка состояние git-репозитория # Настройка учётных данных git-репозитория: git config --global user.email "deviur@yandex.ru" git config --global user.name "Deviur" git add . # добавить файлы для сохранения в git-репозиторий git commit -m'Start Django-project' # сохранить проект # в репозиторий

Пишем проект anfisa4friends

Минимальные изменения

Ниже привожу минимум изменений, которые необходимо сделать в файлах нашего проекта, чтобы всё заработало, как требуется на курсе Яндекса.

Ниже красным обозначено, то что нужно удалить, а синим то, что нужно вставить.

  1. Удаляем все файлы, которых не должно быть в проекте.
  2. В файле ‘settings.py‘ удаляем строку:
    WSGI_APPLICATION = 'anfisa4friends.wsgi.application'
    (остальное можно не менять).
  3. В файле ‘urls.py‘ после строки
    from django.contrib import admin
    вставляем
    from homepage import views as home_views,
    а также, ниже изменяем список urlpatterns на следующий:
    urlpatterns = [
    path('', home_views.index),
    ]
  4. Создаём папку ‘homepage‘.
  5. Создаём в этой папке файл ‘views.py’ со следующим кодом:
    from django.http import HttpResponse
    def index(request):
    return HttpResponse('Anfisa for Friends -- Hello, world! -- ¯(°:°)/¯')

Теперь запускаем проект и смотрим. Всё должно работать!

Что я не стал менять

У нас получилось три версии проекта anfisa4friends:

  1. Версия сохранённая на Яндекс-практикуме.
  2. Версия созданная Django, которую мы сохранили в git-репозитории.
  3. И последняя версия, с изменениями, которые мы сделали в предыдущем разделе.

Часть кода я умышленно не стал делать в точности как на курсе Яндекс-практикума. Код созданный Django мне показался более изящным. Посудите сами:

# Код созданный Django BASE_DIR = Path(__file__).resolve().parent.parent # Код с курса Яндекс-практикума BASE_DIR = os.path.dirname( os.path.dirname(os.path.abspath(__file__)) )

Эти два куска кода делают одно и тоже, но используют две разные библиотеки.

На самом деле, проект Яндекс-практикума не использует базы данных, и не совсем понятно, зачем вообще этот кусок кода в проекте. Я не стал ничего удалять, но закомментировал.

Знакомство с Github.com

Структура git-репозитория

Я планирую повторно пройти курс Яндекс-практикума, но уже на локальном компьютере. Поэтому в git-репозитории проекта будет три ветки:

  1. tasks (задания) — здесь будет код, который дан, как условие в Яндекс-практикуме.
  2. solutions (решения) — здесь мой код, который я предложил в качестве решения и Яндекс его принял, как правильный.
  3. master — основная ветка, в которой вы можете экспериментировать или пройти курс самостоятельно.

Создание структуры веток git-репозитория

У меня Яндекс-практикум уже пройден и сохранены только решения, поэтому начну с ветки solutions.

Для создания ветки и переключения на неё используется следующая команда:

git branch solutions # создание ветки solutions git checkout # переключение на ветку solutions

Теперь сохраню в это ветку последовательно решения всех уроков Яндекс-практикума. В первый коммит будет сохранено моё решение на задачу из темы (topic) №9 урока (lesson) №4.

git commit -m'Solution: topic 9 lesson 4'

Ошибка проверки CSRF. Запрос отклонён.

При прохождении темы 11 на уроке 4 «POST-запросы» на Яндекс-практикуме стала выскакивать эта ошибка. В среде Яндекс-практикума всё работает, а на локальном компьютере, когда нажимаешь кнопку «Угостить» вылетает эта ошибка.

Пришлось покопаться в документации. В результате я внёс небольшие изменения в шаблон ‘index.html

Строку
<form action="/" method="post">,
я заменил на
<form action="/" method="post">{% csrf_token %}

Теперь всё заработало!

Выкладываем наш проект на Github

Для того, чтобы выложить проект на GitHub, у вас должен быть зарегистрированный аккаунт на github.com. У меня аккаунт зарегистрирован под именем «deviur«

Затем вы должны в интерфейсе GitHub создать свой проект. В нашем случае проект будет называться «anfisa4friends«

Далее на нашем локальном компьютере, нужно добавить в git-репозиторий адрес удалённого репозитория.

# Добавляем удалённый репозиторий git remote add origin https://github.com/deviur/anfisa4friends.git # Здесь deviur - моё имя пользователя на GitHub. Не забудьте заменить на своё.А anfisa4friends - это название проекта, который был создан на GitHub.

Теперь остаётся только отправить наш проект на GitHub. Для этого используются следующие команды:

# Отправляем на удалённый репозиторий ветку master git push -u origin master # Отправляем на удалённый репозиторий ветку solutions git push origin solutions

Вот и готово! Теперь наш проект на GitHub-е. Теперь его всегда можно восстановить у себя на компьютере с помощью команды:

git clone https://github.com/deviur/anfisa4friends.git

А ознакомиться с проектом можно по адресу: https://github.com/deviur/anfisa4friends


Задавайте вопросы, пишите пожелания и замечания в комментариях.

Уведомления

  • Начало
  • » Центр помощи
  • » Затык в яндекс практикуме

#1 Фев. 13, 2023 15:36:51

Затык в яндекс практикуме

Здравствуйте. Прохожу бесплатный модуль в практикуме, уперлась во 2й задаче “запросы к друзьям”.

Часть кода дописала, но при выводе выходит “неизвестный запрос”.

Задание: “Сделаем так, чтобы можно было задавать вопросы не только Анфисе, но и самим друзьям, обращаясь к ним по имени. А друзья ответят, в каком они городе.
Добавим в запросы имена. Вопрос к Анфисе будет звучать так: Анфиса, где все мои друзья? Ответ на этот вопрос уже подготовлен, надо лишь немного изменить код.
Если же имя — не «Анфиса», то функция пока не будет ничего делать, этот вариант обработаем в следующей задаче.”

Ниже код, я дописала функцию process_query(query)

 DATABASE = {
    'Серёга': 'Омск',
    'Соня': 'Москва',
    'Миша': 'Москва',
    'Дима': 'Челябинск',
    'Алина': 'Красноярск',
    'Егор': 'Пермь',
    'Коля': 'Красноярск'
}
def format_friends_count(friends_count):
    if friends_count == 1:
        return '1 друг'
    elif 2 <= friends_count <= 4:
        return f'{friends_count} друга'
    else:
        return f'{friends_count} друзей'
def process_query(query):
    elements = query.split(', ')
    if elements[0] == 'Анфиса': 
        process_anfisa(elements[2])
        return process_anfisa(elements[1])
    else: 
        return
    
def process_anfisa(query):
    if query == 'сколько у меня друзей?':
        count = len(DATABASE)
        format_friends_count(count)
        return f'У тебя {format_friends_count(count)}.'
    elif query == 'кто все мои друзья?':
        friends_string = ', '.join(DATABASE)
        return f'Твои друзья: {friends_string}'
    elif query == 'где все мои друзья?':
        unique_cities = set(DATABASE.values())
        cities_string = ', '.join(unique_cities)
        return f'Твои друзья в городах: {cities_string}'
    else:
        return '<неизвестный запрос>'
print('Привет, я Анфиса!')
print(process_anfisa('Анфиса, сколько у меня друзей?'))
print(process_anfisa('Анфиса, кто все мои друзья?'))
print(process_anfisa('Анфиса, где все мои друзья?'))
print(process_anfisa('Анфиса, кто виноват?'))
print(process_query('Соня, ты где?'))

Отредактировано Katerina_25 (Фев. 14, 2023 10:38:15)

Офлайн

  • Пожаловаться

#2 Фев. 13, 2023 23:27:25

Затык в яндекс практикуме

Используй теги code для передачи кода на форуме

[code python]
Тут пиши код
[/code]

Иначе форум стирает табуляции и списки, кавычки заменяет на фуфлокавычки. Потому что думает, что это просто текст, и соответственно, пытается этот текст украсить.

Отредактировано py.user.next (Фев. 13, 2023 23:29:25)

Офлайн

  • Пожаловаться

#3 Фев. 14, 2023 10:38:45

Затык в яндекс практикуме

py.user.next
Используй теги code для передачи кода на форуме

Отредактировала, спасибо

Офлайн

  • Пожаловаться

#4 Фев. 14, 2023 22:52:44

Затык в яндекс практикуме

  
>>> DATABASE = {
...     'Серёга': 'Омск',
...     'Соня': 'Москва',
...     'Миша': 'Москва',
...     'Дима': 'Челябинск',
...     'Алина': 'Красноярск',
...     'Егор': 'Пермь',
...     'Коля': 'Красноярск'
... }
>>> 
>>> def format_friends_count(friends_count):
...     if friends_count == 1:
...         return '1 друг'
...     elif 2 <= friends_count <= 4:
...         return f'{friends_count} друга'
...     else:
...         return f'{friends_count} друзей'
... 
>>> def process_query(query):
...     elements = query.split(', ')
...     if elements[0] == 'Анфиса':
...         return process_anfisa(elements[1])
...     else:
...         return '<неизвестное имя>'
... 
>>> def process_anfisa(query):
...     if query == 'сколько у меня друзей?':
...         count = len(DATABASE)
...         format_friends_count(count)
...         return f'У тебя {format_friends_count(count)}.'
...     elif query == 'кто все мои друзья?':
...         friends_string = ', '.join(DATABASE)
...         return f'Твои друзья: {friends_string}'
...     elif query == 'где все мои друзья?':
...         unique_cities = set(DATABASE.values())
...         cities_string = ', '.join(unique_cities)
...         return f'Твои друзья в городах: {cities_string}'
...     else:
...         return '<неизвестный запрос>'
... 
>>> print('Привет, я Анфиса!')
Привет, я Анфиса!
>>> print(process_query('Анфиса, сколько у меня друзей?'))
У тебя 7 друзей.
>>> print(process_query('Анфиса, кто все мои друзья?'))
Твои друзья: Серёга, Соня, Миша, Дима, Алина, Егор, Коля
>>> print(process_query('Анфиса, где все мои друзья?'))
Твои друзья в городах: Пермь, Красноярск, Челябинск, Омск, Москва
>>> print(process_query('Анфиса, кто виноват?'))
<неизвестный запрос>
>>> print(process_query('Соня, ты где?'))
<неизвестное имя>
>>>

Офлайн

  • Пожаловаться

  • Начало
  • » Центр помощи
  • » Затык в яндекс практикуме

Здравствуйте все! Прохожу бесплатный курс на Яндекс Практикуме по Питону и застрял на одной задаче. Прошу не пугаться, что ниже такой длинный код, на самом деле тут всё просто, изменения нужны небольшие, только я уже 2 часа не могу понять, почему код не работает )). Просмотрел уже не один раз, ну ведь должен он работать )).

В общем суть в том, что программа должна выдать такой результат:

Анфиса, сколько у меня друзей? — У тебя 7 друзей
Анфиса, кто все мои друзья? — Твои друзья: Сергей, Соня, Миша, Дима, Алина, Егор, Коля
Анфиса, где все мои друзья? — Твои друзья в городах: Омск, Москва, Красноярск, Пермь, Челябинск
Анфиса, кто виноват? — <неизвестный запрос>
Коля, ты где? — Коля в городе Красноярск
Соня, что делать? — <неизвестный запрос>
Антон, ты где? — У тебя нет друга по имени Антон

Уберу в спойлер формулировку задания:

2.
А. Напишите функцию process_friend(name, query), принимающую имя друга name и запрос query.

  • Если друга с указанным именем ‘Н’ нет в списке, то функция должна вернуть сообщение об ошибке У тебя нет друга по имени Н.
  • Если запрос — «ты где?», то функция должна вернуть сообщения ‘Н в городе Г’, где Г определяется по данным словаря DATABASE.
  • Если запрос не «ты где?», а какой-то другой, то функция должна вернуть сообщение об ошибке <неизвестный запрос>.

Б. Допишите функцию process_query(). Если запрос начинается не с «Анфиса», а с другого имени, то вызовите функцию process_friend(name, query), передав в неё имя друга и тело запроса. И верните результат выполнения этой функции.
В. Добавьте в список queries новые запросы вида:

  • Коля, ты где?
  • Соня, что делать?
  • Антон, ты где?

Что-то неправильно написано в функции process_friend или в функции process_query. У меня получается такой результат (последние строки почему-то выводятся все в одну строку):

Анфиса, сколько у меня друзей? — У тебя 7 друзей
Анфиса, кто все мои друзья? — Твои друзья: Сергей, Соня, Миша, Дима, Алина, Егор, Коля
Анфиса, где все мои друзья? — Твои друзья в городах: Омск, Москва, Красноярск, Пермь, Челябинск
Анфиса, кто виноват?Коля, ты где?Соня, что делать?Антон, ты где? — <неизвестный запрос>

А вот код:

Python:

DATABASE = {
    'Сергей': 'Омск',
    'Соня': 'Москва',
    'Миша': 'Москва',
    'Дима': 'Челябинск',
    'Алина': 'Красноярск',
    'Егор': 'Пермь',
    'Коля': 'Красноярск'
}


def format_count_friends(count_friends):
    if count_friends == 1:
        return '1 друг'
    elif 2 <= count_friends <= 4:
        return f'{count_friends} друга'
    else:
        return f'{count_friends} друзей'


def process_anfisa(query):
    if query == 'сколько у меня друзей?' or query == 'колько у меня друзей?': # был какой-то глюк тренажера и пришлось добавить фразу 'колько у меня друзей?' 
        count_string = format_count_friends(len(DATABASE))
        return f'У тебя {count_string}'
    elif query == 'кто все мои друзья?':
        friends_string = ', '.join(DATABASE.keys())
        return f'Твои друзья: {friends_string}'
    elif query == 'где все мои друзья?':
        unique_cities = set(DATABASE.values())
        cities_string = ', '.join(unique_cities)
        return f'Твои друзья в городах: {cities_string}'
    else:
        return '<неизвестный запрос>'

    
def process_query(query):
    tokens = query.split(', ')
    name = tokens[0]
    if name == 'Анфиса':
        query = query.strip('Анфиса, ')
        return process_anfisa(query)
    else:
        query = query.strip('Коля, ')
        return process_friend(name, query)
        
def process_friend(name, query):
    if name in DATABASE:
        if query == 'ты где?':
            city = DATABASE[name]
            return f'{name} в городе {city}'
        else:
            return '<неизвестный запрос>'
    else:
        return f'У тебя нет друга по имени {name}'
    
        
def runner():
    queries = [
        'Анфиса, сколько у меня друзей?',
        'Анфиса, кто все мои друзья?',
        'Анфиса, где все мои друзья?',
        'Анфиса, кто виноват?'
        'Коля, ты где?'
        'Соня, что делать?'
        'Антон, ты где?'
    ]
    
    for query in queries:
        print(query + ' - ' + process_query(query))


runner()

Понравилась статья? Поделить с друзьями:
  • Яндере симулятор ошибка при скачивании
  • Яндекс почта создать правило произошла ошибка
  • Яндекс такси ошибка при проверке карты
  • Яндекс почта ошибка соединения
  • Яндекс станция ошибка отсутствует подключение к интернету