Здравствуйте, Александр!
Уточните, пожалуйста, вы пытаетесь совершить первую оплату?
Александр, первую оплату вы совершаете самостоятельно. После оплаты первого платёжа привязывается карта, с которой автоматически спишутся следующие, раз в 30 дней. Мы сможем помочь списать только следующие оплаты, если будут возникать трудности.
Если нужна помощь, пишите — во всём разберёмся вместе :)
Александр, выбранный вами курс стартует 16 августа, вероятнее всего, срок оплаты будет продлён до 15 августа :)
Дайте знать, если можем ещё чем-либо помочь:)
Александр, вероятнее всего, срок оплаты будет продлём до 15 августа, если до этого времени не будет набран поток :)
Не переживайте, если вы оплатите на следующей неделе, вы будете зачислены в поток :)
Александр, если вы оплатите курс на следующей неделе, ты вы попадете в ближайший поток :)
Так и есть, но место для вас найдётся :) Остались ли у вас ещё какие-то вопросы ?
Добрый день, Александр!
Для оплаты обучения, перейдите в свой профиль: https://praktikum.yandex.ru, выберите профессию, которую планируете изучать, далее нажмите на кнопку вверху «Купить полную программу», выберите подходящий вам способ оплаты и следуйте инструкциям системы.
Если возникнут вопросы — обязательно пишите :)
Подскажите, вы оплачиваете курс картой банка РФ или иностранного банка?
Уточните,
пожалуйста, почту из вашего аккаунта в Практикум, выбранный курс и
способ оплаты (ежемесячными платежами или полностью) — пришлём ссылку
для оплаты и запишем в группу.
При оплате ежемесячными платежами мы будем формировать новую ссылку каждый месяц и присылать также в письме.
Если вы не против, уточните, пожалуйста, страну вашего проживания — стараемся расширять географию оплаты на сайте и хотим понимать, куда двигаться :)
Александр, отправили вам ссылку в отдельном письме. После оплаты придёт кассовый чек, это значит, что всё прошло успешно и мы получили деньги. После оплаты мы включим вас в 5 поток, который стартует 16 августа.
Cумма ежемесячного платежа составит 12 825руб с учетом скидки 5% за подписку Яндекс.Плюс, мы будем присылать вам ссылку на оплату ежемесячно, всего их будет 14, как и месяцев в курсе Python-разработчик Плюс. Оплата по ссылке проводится в российских рублях.
В день старта потока вам придет важное письмо на почту и куратор примет вас на борт.
Удачи в учебе! А если будут вопросы - пишите, мы рядом.
Сейчас мы пришлем вам новую ссылку с учетом промокода SECOND :)
Александр, первую ссылку мы деактивировали, стоимость обучения для вас составит 11475руб в месяц вместо 13500руб с учетом скидки 15% (5% за Плюс + 10% по промокоду SECOND). Всего будет, как писали ранее, 14 ссылок, и итоговая стоимость курса для вас составит 160 650руб вместо обычных 189 000руб :)
Здравствуйте, Александр!
Наш специалист напишет вам утром и вы во всём разберётесь, хорошо ?:)
Грустить осталось недолго :)
Александр, наши коллеги работают по будням с 10 до 19 :)
Ожидайте, пожалуйста 🌿
Александр, добрый день,
Оплата по ссылке прошла успешно. В течение дня статус оплаты в личном кабинете поменяется:)
Мы записали вас в 5 поток, который стартует 16 августа. В личном кабинете у вас не должно быть ошибки об оплате, проверьте, пожалуйста:)
Обязательно пишите, если у вас появятся вопросы до старта:)
Здравствуйте, Александр!
Пришлите, пожалуйста, ссылку на ваш код, записанный на сайте https://pastebin.com/ и ссылку на саму задачу — посмотрим, в чём там дело :)
Подождём :) Что-то не так ?
Такое бывает :) Если понадобится наша помощь — напишите, мы тут как тут.
Давайте обратимся к теории задания :) Вот код, который можно там найти
return render(request, 'homepage/homepage.html', context)
Нашли свою ошибку ?
С синтаксисом нужно быть осторожным; то, что вы написали, по факту не совсем правильно :) В прекоде есть такая строчка
Как вернуть из view-функции функцию render? Вот так: `return render(аргументы-аргументы-аргументы)
А вы записали
аргументы-аргументы-аргументы=аргументы
Остались ли у вас ещё какие-то вопросы ?
Рады были помочь :)
Здравствуйте, Александр! Обновите, пожалуйста, сейчас страницу курса. Всё должно встать на свои места.
А
так, уже заканчиваем последние приготовления. В течение дня по
московскому времени откроется доступ к платной части, сперва мы
познакомимся, а в Slack куратор подробнее расскажет про то, что будет
дальше. Приглашение в Slack направим на почту — иногда оно попадает в
папки Спам или Рассылки, советуем поглядывать и туда.
Уточните, пожалуйста, вы указывали новую почту для приглашения в slack или ту же, что используете на другом курсе?
Там сейчас у вас только каналы для профессии Python-разработчик , а других каналов, которые были нет, правильно понимаем?
Хорошо, спасибо! Уточним вопрос у коллег и вернёмся к вам с ответом :)
С вами свяжется куратор и добавит в нужные каналы.
Дайте знать, если ещё чем-то можем вам помочь :)
Сейчас куратор напишет в новом аккаунте :)
Здравствуйте!
Также, просим проверить, что в личном кабинете Яндекс Паспорта https://passport.yandex.ru/ привязана карта, с которой необходимо совершить оплату.
Если карта не привязана, просим привязать её и сообщить нам 4 последние цифры карты.
Отправили запрос на списание, если всё пройдёт успешно, то в течение 10-15 минут денежные средства спишутся, вам на почту придёт чек о списании и статус в профиле изменится. Дайте знать, если этого не произойдёт.
Здравствуйте!
Александр, уточните, пожалуйста, ваш логин в Практикуме — alexander.borovtsoff@yandex.by? Не могли бы также уточнить, когда вы в последний раз оплачивали курс Аналитик данных?
Александр, уточните, пожалуйста, последние 4 цифры вашей карточки, привязана ли она к вашему аккаунту? Также, пожалуйста, убедитесь, что у вас на карте достаточно средств для проведения платежа — оплатить необходимо 13000 рублей.
Александр, провели платёж — уточните, пожалуйста, списались ли средства теперь? :)
None
. В таких случаях для аннотирования типов данных применяют компоновщики.Скопировать кодPYTHON# Компоновщики импортируются из модуля typing
from typing import <имя_компоновщика>
<имя переменной>: <имя_компоновщика>[<описание_типов_данных>]
None
; например — str
и None
, bool
и None
.None
не указывается в компоновщике Optional в явном виде:Скопировать кодPYTHONfrom typing import Optional
# Переменная text ожидает данные типа str или None
text: Optional[str]
# Эксперимент: в переменную с типом "строка"...
var: str
# ...передадим None:
var = None
# Анализатор кода сообщит об ошибке:
# Incompatible types in assignment
# (expression has type "None", variable has type "str")
# А переменная text аннотирована через Optional, и если передать в неё None...
text = None
# ...проблем не будет.
Скопировать кодPYTHONfrom typing import Union
# Аргумент x может принимать целое число или строку
def hundreds(х: Union[int, str]) -> str:
return str(х * 100)
hundreds(100)
hundreds('сто')
Optional[<тип_данных>]
эквивалентна Union[<тип_данных>, None]
.Скопировать кодPYTHONfrom typing import Any
x: Any
x = 12210
x = 'Строка'
x = True
x = None
# Можно всё! Переменная x примет любой тип данных.
Скопировать кодPYTHONfrom typing import Sequence, Dict, List, Tuple, Set
# Это множество может принять только целые числа
var_set: Set[int] = {1, 2, 3, 4, 5, 6,}
# Словарь
# <имя_переменной>: Dict[<тип_ключа>, <тип_значения>]
# Ключ аннотирован как строка, а значение - как целое число
var_dict: Dict[str, int] = {'forty_two': 42, 'hundred': 100,}
# Список
# <имя_переменной>: List[<тип_значения>]
var_list: List[int] = [1, 2, 3, 4,]
# Кортеж с определённой длиной (перечисляются типы всех элементов)
# <имя_переменной>: Tuple[<тип_элемента_1>, <тип_элемента_2>, <тип_последнего элемента>]
var_tuple: Tuple[int, int, str, float] = (1, 2, 'привет', 1.618,)
# Кортеж с переменной длиной
# <имя_переменной>: Tuple[<тип_всех_элементов>, ...]
# Многоточие (Ellipsis) - это указание для Python, что длина кортежа не определена
var_tuple: Tuple[float, ...] = (1, 2, 3.4,)
# Универсальный тип Sequence (Последовательность),
# подойдёт для аннотирования списка или множества
# <имя_переменной>: Sequence[<тип_всех_элементов>]
# принимает список
var_sequence: Sequence[float] = [1.2, 2, 3,]
# и принимает множество
var_sequence: Sequence[float] = {1.2, 2, 3,}
Скопировать кодPYTHONfrom typing import Tuple, Union
var_tuple: Tuple[Union[str, int, bool], ...] = (True, 13, 'наш кортеж',)
Скопировать кодPYTHONfrom typing import Dict, List, Union
# Создан псевдоним для сложного типа данных:
CustomDict = Dict[str, List[Union[int, str]]]
# Указание этого типа для переменной (через псевдоним)
def just_return_it(incoming: CustomDict) -> CustomDict:
return incoming
# Указание того же типа для переменной (без псевдонима)
def just_return_it(incoming: Dict[str, List[Union[int, str]]]) -> Dict[str, List[Union[int, str]]]:
return incoming
# Выгода налицо: псевдоним сбережёт время и нервы.
Скопировать кодPYTHONfrom typing import Callable
# Callable[[<тип аргумента 1>, <тип аргумента 2>,...], <возвращаемый тип>]
def printer() -> None:
print("Вызови меня!")
def returner(word: str) -> str:
return word
def app(printed_inside: Callable[[], None], returned_inside: Callable[[str], str]) -> None:
printed_inside()
print(returned_inside('Нет, вызови меня!'))
# При таком вызове всё будет ok:
app(printer, returner)
# А если во второй аргумент передать функцию,
# которая ничего не принимает и не возвращает...
app(printer, printer)
# ...mypy сообщит об ошибке:
# error: Argument 2 to "app" has incompatible type "Callable[[], None]";
# expected "Callable[[str], str]"
# "Передан вызываемый объект, который ничего не принимает и не возвращает,
# а ожидался объект, который на вход примет строку и вернёт строку. Непорядочек."
Скопировать кодPYTHONfrom typing import Callable
# Вместо типов аргументов для Callable можно поставить Ellipsis (три точки)
# В случае использования Ellipsis квадратные скобки [] не нужны.
def app(printed_inside: Callable[[], None], returned_inside: Callable[..., str]) -> None:
printed_inside()
print(returned_inside('Нет, вызови меня!'))
Скопировать кодPYTHONclass WeirdObject:
def work(self) -> None:
print("Работает")
# Функция dependency_func() ожидает на вход объект класса WeirdObject:
def dependency_func(obj: WeirdObject) -> None:
obj.work()
# Создаём объект класса WeirdObject
strange_item: WeirdObject = WeirdObject()
# При таком вызове всё будет ok (в функцию передаётся объект класса WeirdObject):
dependency_func(strange_item)
>>> Работает
# А такая запись будет отмечена линтером как ошибка:
dependency_func(11)
# error: Argument 1 to "dependency_func" has incompatible type "int";
# expected "WeirdObject"
# "В функцию передано число, а мы-то ожидали объект класса WeirdObject!"
bool
, str
или int
.
Начиная с версии Python 3.7 можно заглянуть в будущее — специальный
импорт даёт возможность уже сейчас применять новый синтаксис: названия
типов dict, list, tuple и set нужно будет писать с маленькой буквы. Скопировать кодPYTHON# Импорт из будущего
from __future__ import annotations
# И теперь можно работать коллекциями как со встроенными типами
# Список
var_list: list[str] = ['Ура', 'типы', 'можно', 'не импортировать отдельно!', ]
# Словарь
var_dict: dict[str, float] = {"версия языка": 3.7, }
Скопировать кодPYTHONclass CarTracer:
"""Отслеживание автомобиля по номеру."""
# Тут второй аргумент аннотирован типом Position,
# но этот тип будет объявлен позже. Возникнет ошибка: "Неизвестное имя!"
def __init__(self, number: int, position: Position) -> None:
self.number = number
self.position = position
# Класс Position объявлен после того, как использован в типизации
class Position:
"""Определяет широту и долготу."""
def __init__(self, altitude: float, latitude: float) -> None:
self.altitude = altitude
self.latitude = latitude
NameError: name 'Position' is not defined.
position
(в начале кода) указан тип Position
, который объявляется ниже, ближе к концу кода. Изменить же порядок кода зачастую бывает невозможно.Position
в кавычки: анализатор аннотаций всё равно поймёт, что вы имели в виду, а интерпретатор кода не споткнётся о незнакомое имя. Скопировать кодPYTHONdef __init__(self, number: int, position: 'Position') -> None:
...
annotations
из «пакета будущего»:Скопировать кодPYTHONfrom __future__ import annotations
class CarTracer:
"""Отслеживание автомобиля по номеру."""
def __init__(self, number: int, position: Position) -> None:
self.number = number
self.position = position
def __str__(self) -> str:
return (f'Координаты автомобиля номер {self.number},: '
f'{self.position.altitude}, {self.position.latitude}')
class Position:
"""Определяет широту и долготу."""
def __init__(self, altitude: float, latitude: float) -> None:
self.altitude = altitude
self.latitude = latitude
moscow: Position = Position(55.7522, 37.6156)
car778: CarTracer = CarTracer(778, moscow)
print(car778)
from __future__ import annotations
.lower_join()
. Логика работы функции описана в docstringtyping
.join
работает только со строками, так что функция ожидает список строк. Если передать в join
числа — будет ошибка.series_sum()
. Логика работы функции описана в docstring.typing
.add()
описана в docstring.float
принимает и те, и другие.xxxxxxxxxx
from typing import List, Union
def series_sum(incoming: List[Union[str, float]]) -> str:
"""Принимает на вход список, приводит его элементы к строкам
и конкатенирует их.
"""
result = ''
for i in incoming:
result += str(i)
return result
series_sum([1, '-', 2, '-', 3, '-', 4, '-', 5, ' - буду', ' ан-', 'но-', 'ти-', 'ро-', 'вать!',])
series_sum([1, '-', 2, '-', 3, '-', 4, '-', 5, ' - буду', ' ан-', 'но-', 'ти-', 'ро-', 'вать!',])