Русский
Русский
English
Статистика
Реклама

Developer

Kubernetes для разработчиков трехдневный интенсив

19.11.2020 18:06:36 | Автор: admin
image

Спикеры Слёрма готовят обновленный интенсив, в котором не будет тем для администраторов. Мы убрали тему про обслуживание кластера и сосредоточились на особенностях разработки ПО в Kubernetes. В программе только то, что действительно нужно современному разработчику на проектах с K8s.

Почему трехдневный интенсив?


В Слёрме прошло уже 14 трехдневных интенсивов по Kubernetes, и мы уверены, что такой формат дает крутые результаты. К вечеру третьего дня студенты знают, что такое Kubernetes, что в нём есть и как в нём работать. Выпускник интенсива может свободно читать документацию по K8s и понимать её. Можно возвращаться и пересматривать материалы, когда понадобится. Интенсив возможность быстро запустить подготовку специалиста. Важно помнить, что такое обучение невозможно совместить с работой (учимся с 10 до 19, отвлекаться не получится).

Короткая история одного разработчика про K8s


Вот что рассказывает про обучение Артем из Gismeteo:
Я backend-разработчик в команде Gismeteo. Занимаюсь поддержкой и разработкой существующего погодного API, настройкой CI|/CD Gitlab, написанием ролей на Ansible, выкладкой на продакшн.

В компании мы в какой-то момент приняли решение избавиться от LXC-контейнеров в пользу Docker. Так как у нас highload, одним контейнером мы бы не отделались. Из этого появился вопрос: как за этим всем следить и управлять. Поэтому мы и решили присмотреться к Kubernetes, я стал искать возможности для обучения. Читал документацию, но информация, которая там есть, подходит только для ознакомления. Без практики это пустая трата времени. Пытался смотреть видео на Ютюбе, но, опять же, не хватало практики.

Тогда я решил пойти на практический курс, выбрал интенсив Слёрма. Хотел познакомиться ближе с принципами работы k8s, узнать best practices от спикеров. Интенсивное обучение мне хорошо подошло, помощь техподдержки не понадобилась. Самым интересным моментом на курсе, по-моему, было добавление rollback piplin'a для отката версии Docker-образа. Я любитель CI/CD, поэтому для меня это было особенно актуально. Также понравилась тема про интеграцию CI/CD с Kubernetes через Helm. Сложной практической темой оказалось написание своего helm chart'a.

После курса я убедился в том, что Kubernetes на текущий момент времени лучший оркестратор для контейнеров. Продолжаю повышать квалификацию в этом направлении, теперь уже на рабочих задачах. Сейчас пересматриваю материал курса, связанный с helm, так как пересобираю сейчас все наши ci/cd под диплойку через helm. Очень удобная вещь.

Ссылка на отзыв в ВК

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

Kubernetes для разработчиков пройдет 35 марта 2021, но уже сейчас можно забронировать место до конца 2020 участие стоит 20 000 рублей.
Подробнее..

Перевод Отношение один к одному связывание модели пользователя с кастомной моделью профиля в Django

05.10.2020 16:20:50 | Автор: admin
Перевод статьи подготовлен в преддверии старта курса Web-разработчик на Python.



Пфф Снова базы данных?



В реляционной базе данных есть три основных отношения:

  • Отношение один-к-одному;
  • Отношение один-ко-многим;
  • Отношение многие-ко-многим.


В этой статье мы будем разбираться с первым из них отношением один-к-одному.

Обычно в Django уже есть модель пользователя, которая поставляется с фреймворком. Она поставляется со своими полями, методами, атрибутами и т.д. Недостатком этой модели пользователя является то, что она не позволяет добавлять специальные поля отдельно от значений по умолчанию уже представленных в Django. Это может стать серьезной проблемой, поскольку разработчику может понадобиться полностью настроить профиль пользователя/клиента из группы аутентифицированных пользователей. Например, сайту блога может понадобиться профиль автора, который будет включать в себя фотографию пользователя, контактный адрес, хобби, нишу и т.д. А модель пользователя, поставляемая с Django, не позволяет так сделать.

Чтобы решить эту проблему, разработчики создают кастомную модель профиля и соединяют ее с моделью пользователя в Django по умолчанию с помощью отношения один-к-одному. Так получается, что пользователь гарантированно подключен к одному профилю и наоборот. Кроме того, эта механика позволяет лучше управлять настройкой модели профиля.

Теперь я расскажу вам, как в Django можно сделать такую настройку.

1. Используйте модель пользователя в Django по умолчанию
В том приложении, где вы хотите создать профиль, создайте новый файл forms.py. В forms.py импортируйте следующие модули:

from django.contrib.auth.forms import UserCreationFormfrom django.contrib.auth.models import User


Создайте класс, который будет наследоваться от UserCreationForm. Внутри этого класса создайте другой мета-класс, у которого будут две переменные: model и fields. В переменной model будет храниться ваша модель пользователя, а в переменной fields поля формы, которые будут созданы.

class createUserForm(UserCreationForm):    class meta:        model = User        fields = ['username', 'password1', 'password2']


Код выше создаст форму с полями для имени пользователя, пароля и подтверждения пароля.

2. Создайте свою кастомную модель профиля пользователя.
В файле models.py импортируйте модель пользователя по умолчанию.

from django.contrib.auth.models import User


Дальше нужно создать свою модель профиля, а также создать поле пользователя со связью один-к-одному с моделью пользователя по умолчанию в Django.

class Profile(models.Model):    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True,)    name = models.CharField(max_length=200, null=True)    email = models.CharField(max_length=200, null=True)    address = models.CharField(max_length=200, null=True)    def __str__(self):        return self.name


3. Создайте форму для своей модели профиля.
Откройте файл form.py и импортируйте свою модель профиля из models.py, также добавьте несколько других импортов, которые пригодятся при создании формы профиля.

from django import formsfrom django.utils.translation import ugettext_lazy as _from .models import Profile


Затем создайте класс, который будет наследоваться от forms.ModelForm. В этом классе создайте другой мета-класс, в котором будут две переменные: model и fields. Переменная model содержит модель профиля, а fields поля формы, которые будут созданы.

class profileForm(forms.ModelForm):    class Meta:        model = Profile        fields = ['name', 'email', 'address']#The labels attribute is optional. It is used to define the labels of the form fields created           labels = {                "name": _("Name     "),                "email": _("Email Address"),                "address": _("Street Address"),                }


Теперь, когда формы готовы, мы определим логику views.py перед тем, как рендерить его в наши шаблоны.

4. Пропишите логику в views.py
Для работы с формами, созданными в forms.py нужно импортировать их в наш views.py, и добавить еще несколько модулей, которые пригодятся для создания логики.

from django.shortcuts import render, redirectfrom django.contrib.auth import authenticate, login,from django.contrib import messagesfrom .models import Profilefrom .forms import createUserForm, profileForm


Теперь создадим страницу регистрации. Назовем ее просто registerPage. Создадим пустой контекстный словарь и вернем рендер.

def registerPage(request):        context = {}    return render(request, 'app_name/register.html', context)


Присвоим значения из формы переменным, вызвав метод POST. Затем передадим переменные в контекстный словарь.

def registerPage(request):    if request.method == 'POST':        form = createUserForm(request.POST)        profile_form = profileForm(request.POST)    context = {'form': form, 'profile_form': profile_form}    return render(request, 'app_name/register.html', context)


Затем мы сделаем валидацию обеих форм и сохраним их после нее.

def registerPage(request):    if request.method == 'POST':        form = createUserForm(request.POST)        profile_form = profileForm(request.POST)        if form.is_valid() and profile_form.is_valid():            user = form.save()            #we don't save the profile_form here because we have to first get the value of profile_form, assign the user to the OneToOneField created in models before we now save the profile_form.             profile = profile_form.save(commit=False)            profile.user = user            profile.save()    context = {'form': form, 'profile_form': profile_form}    return render(request, 'app_name/register.html', context)


Если значения форм валидированы и сохранены, мы выведем сообщение об успешном выполнении операции и перенаправим пользователя на страницу входа в систему.

def registerPage(request):    if request.method == 'POST':        form = createUserForm(request.POST)        profile_form = profileForm(request.POST)        if form.is_valid() and profile_form.is_valid():            user = form.save()            #we don't save the profile_form here because we have to first get the value of profile_form, assign the user to the OneToOneField created in models before we now save the profile_form.             profile = profile_form.save(commit=False)            profile.user = user            profile.save()            messages.success(request,  'Your account has been successfully created')            return redirect('login')    context = {'form': form, 'profile_form': profile_form}    return render(request, 'app_name/register.html', context)


5. Рендер шаблона
В файле register.html создадим тег формы с помощью метода POST и action со значением пустой строки. В тег формы поместим csrf_token в формате шаблона django, а затем будем динамически визуализировать формы (форму пользователя и профиля). Также не забудем про кнопку отправки.

<form method="POST" action="">                {% csrf_token %}                    <h3>Register Profile</h3>                    <div class="form-field">                        {{profile_form.name.label_tag}}                        {{profile_form.name}}                    </div>                    <div class="form-field">                        {{form.username.errors}}                        {{form.username.label_tag}}                        {{form.username}}                    </div>                    <div class="form-field">                        {{profile_form.email.label_tag}}                        {{profile_form.email}}                    </div>                    <div class="form-field">                        {{profile_form.address.label_tag}}                        {{profile_form.address}}                    </div>                    <div class="form-field">                        {{form.password1.errors}}                        {{form.password1.label_tag}}                        {{form.password1}}                    </div>                    <div class="form-field">                        {{form.password2.errors}}                        {{form.password2.label_tag}}                        {{form.password2}}                    </div>                <hr>                <input id="form-button" class="btn btn-success btn-block" type="submit" value="Create Profile">                <br>                    {{form.non_field_errors}}                <p>Already have an account? <a href="{% url 'login' %}">Login</a></p>            </form>


Поскольку после заполнения формы, ее проверки и сохранения, мы перенаправляем на страницу входа в систему, сообщение об успешности операции будет отображаться на странице входа в систему снизу прямо перед надписью Don't have an account? Register.





{% for message in messages %}

{{message}}


{% endfor %}

Don't have an account? Register




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


Подробнее..

Эволюция моих SQL запросов

26.01.2021 00:16:12 | Автор: admin

Всем привет! Я тимлид и Senior Oracle Developer, 12 лет работаю с OeBS и в основном пишу SQL запросы. Хотел бы рассказать, как за это время менялся мой подход в написании SQL запросов.

Вначале было слово, а точнее запрос. Скажем

select name from user where id = 1

Написать такой запрос как-то не так практически невозможно. Он одинаково хорошо работает во всех известных мне базах данных. А знаю я только oracle :З Но подозреваю что и в других реляционных тоже всё будет ок.

Так что же произошло? Проблемы начались, когда таблиц стало две:

select name from user u, rest r where u.id = 1 and u.id = r.user_id

Этот код вызывал у меня больше вопросов. Например, как должны быть соединены эти таблицы? Казалось бы что проще id = user_id, но мне что-то не нравилось. В блоке where мне не хватало четкого разделения между условиями фильтрации и соединениями таблицам. Когда запрос содержал 2 таблицы всё ещё было норм, но когда кол-во таблиц доходило до 5 - всё рассыпалось. Взглянув на запрос, я не мог сразу понять как соединены таблицы и не пропущена ли какая-то связка. И с этим все прекрасно жили, но я не мог. Однажды мне, молодому джуну, на глаза попался ANSI синтаксис.

select name from user inner join rest on u.id = r.user_id where u.id = 1

букв стало немного больше, но я намного лучше стал понимать, как связаны таблицы в моих SQL выражениях. Мир запросов расцвёл для меня новыми красками, и я больше не писал запросы как-то иначе. А ещё распространял эту весть среди других джунов. Это был мой первый шаг в эволюции SQL. Я вырвался от привычных шаблонов легаси кода и сделал что-то своё. Но была одна проблема. Когда используется скажем левостороннее соединение ANSI синтаксис заставляет переносить в связки, и все прочие ограничения для таблицы.

select u.name, r.resp_name from user u left join resp r on u.id = r.user_id  and r.end_date > sysdate where id = 1

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

select resp_q as (  select resp_name, userid   from resp where r.end_date > sysdate) ,main_q as (   select u.name, r.respname   from user u    left join resp_q r on u.id = r.userid   where id = 1) select * from main_q

Кода стало опять большое, но запросы в with позволили мне разбить монолитный запрос и группировать разные кусочки запроса по историям, а потом сплетать их вместе. Я мог рассказать про свой запрос так: Получаем список пользователей. Список ролей. Объединяем их в одну выборку и отсекаем тех кто нам не нравится. С оставшимися идём дальше, взявшись за руки. И за каждый шаг отвечала свой небольшой именованный запрос. Это также помогло мне бороться с моим злейшим врагом WET, т.к. одни и те же истории я мог использовать в разных частях своего запроса, не дублируя код. Ко всему прочему, упростилась отладка. Знай в блок from подставляй разные именованные запросы и отлаживай их по отдельности. А ещё, как выяснилось позже, с помощью with можно оптимизировать запросы, используя hint MATERIALIZE. Он материализует именованный подзапрос и данные при запросе из него берутся из темпового пространства. До этого я использовал обычные темповые таблицы. Это было более грубое решение, т.к. создавались лишние объекты БД + надо было помнить про очистку. Как итог, теперь, если запрос сложнее 10 строк, я почти всегда использую with.

Но чего-то не хватало. По своей природе я люблю кодить, но, когда приходит время тестировать, весь мой энтузиазм куда-то пропадает. Как итог, я часто отдавал не до конца протестированный код. Мне регулярно приходилось слышать про unit тесты, автотесты и прочее. Но сложно было это применить к БД. Сегодня сумма за период равна 100р, а завтра 120р. И как ты тут напишешь тест? Так и жил Но, уже став тимлидом, мне попалась задача, в которой надо было найти отмененные документы. Условие отмены было достаточно сложным и собиралось из множества нюансов (спрятал под функцию).

select * from document where xxstorno(id) = 'Y'

У меня было порядка 10 примеров документов. И завершая условие для одного документа, что-то ломалось в другом. А так как тестировал руками и глазами, времени уходило просто море. Я уже думал этому не будет конца. Пока не понял, что вокруг моего запроса можно написать обертку, которая будет за меня проверять все мои кейсы и говорить какие документы прошли проверку, а какие нет. Потратив на обертку несколько минут, я сократил время тестирования с 5-7 минут, до нескольких секунд.

with test_case as (  select 10 id, 'Y' storno from dual   union all   select 5 id, 'N' storno from dual)  , run_test as (    select tc.id, decode(xxstorno(d.id), tc.storno, 'OK', 'Error') result    from test_case tc    left join documentd on d.id = tc.id) select * from run_test

После правки функции, я просто запускал тест-запрос и смотрел сколько документов прошло тестирование, а сколько нет. В процессе тестирования я накидывал туда ещё кейсов, при том что про старые тесты тоже не забывались. И тогда я понял, как же это здорово! Как можно легко тестировать свой запрос, повышать надёжность и при этом не нужно ничего делать руками. Это может показаться элементарным, но до этого мне не встречались подобные конструкции. Обычно я видел конструкции типа and id = 5--6 7 10 135 1345 в которой просто перебором подставлялись разные значения и руками смотрелось что и как оно должно возвращать. С того дня я написал несколько разработок, и к каждой из них я уже готовил свой тестовый скрипт. Данный стиль мне очень понравился и теперь я пытаюсь привить его и своим разработчикам. Чтобы им не пришлось проделать путь в 12 лет, чтобы писать красивые SQL запросы.

По итогу в мире SQL не происходит почти ничего нового уже много лет, тем не менее всегда приятно найти возможность улучшить свои запросы.

Подробнее..
Категории: Sql , Oracle , Developer , Pl/sql

Головоломки Tech Monsters Night

19.06.2021 14:07:57 | Автор: admin


Совсем недавно М.Видео-Эльдорадо в рамках хакатона Tech Monsters Night предложили всем желающим стать участниками интеллектуальной битвы, решив серию головоломок.

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

Под катом серия предложенных участникам Tech Monsters Night задач. Таким образом, у вас есть чудесная возможность провести наступившие выходные за решением этих головоломок. Есть предложение: в начале мы публикуем задания, вы в комментариях размещаете варианты решений. А через пару дней в обновлениях к данному посту мы разместим правильные ответы.

1. Унести с места


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

Входные данные: строка распределения весов в ряду
Пример входных данных: 1,2,0 введенные веса грузов в каждом ряду.

Подряды:
2,0: 2+0 = 2 количество цифр
1: 1 = 1 количество цифр
1,2,0: 1+ 2 + 0 = 3 количество цифр

Выходные данные: количество рядов подходящих под условие

Пример ответа: 3
Тестовые пары:?

2. Мультиварки


Условие:
В магазине есть мультиварки k видов. Дано количество мультиварок каждого вида и их цена за штуку. Покупателю нужно купить t мультиварок.
Необходимо продать мультиварки, чтобы суммарная стоимость была максимальна.

Входные данные: Строка, в которой пары чисел разделены точкой с запятой (";"). Первая пара чисел содержит значения [t,k], а последующие количество мультиварок каждого вида n, и их стоимость p. [n,p]. Все пары чисел разделены запятой (",")

Пример входных данных: 7,3;5,10;2,5;3,6

Три вида мультиварок:
  • первый вид 5 штук, стоимостью по 10,
  • второй вид 2 штуки стоимостью по 5,
  • третий вид 3 штуки стоимостью по 6.

Выходные данные: суммарная максимальная стоимость

Пример ответа: 62
Тестовые пары:?

3. Наушники


Условие:
Нужно предсказать возможно ли при условиях, описанных ниже, чтобы в магазинах бытовой техники Tune 66 в наличии всегда было от a до b штук наушников. Известно, что их покупают ровно t штук ежедневно.

Изначально в магазинах содержалось h штук, при этом привозятся в магазины ровно k штук в начале каждого дня, начиная от второго дня. Будет ли количество наушников держаться в нужном диапазоне в течении s дней?

Входные данные: Строка, содержащая параметры: h,a,b,s,t, k. Числа в строке разделены запятой (",")

Ответ: 1 если да, 0 если нет
Тестовые пары:?

4. Акция


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

Покупатель получает половину, округленное в меньшую сторону содержимого выбранных баночек и уносит, вместе с одной из банок. Остальные монеты складываются в оставшуюся банку и она дальше участвует в розыгрыше, совместно с оставшимися. Найдите сколько максимум в ходе розыгрышей выиграют все покупатели за k-1 шагов.

Пример: пусть k = 4, тогда изначально есть баночки с [1,2,3,4] монетами, сначала берем 4 и 2 баночку. Покупатель уносит 3 монеты, а оставшиеся 3 монеты оставляет на месте 2 баночки. Тогда остается [1,3,3]. Следующий покупатель выбирает 2 и 3 банку, забирает половину их содержимого, т.е 3 монеты, и оставляет на месте 2 банки, вторую половину, то есть ещё 3 монеты. Тогда остается [1,3]. Дальше разыгрывается первая и вторая банка, покупатель забирает 2 монеты, и остается 2, т.е [2].

Входные данные: число k
Ответ: сколько максимум выиграли в сумме все покупатели?
Пример ответа: 8
Тестовые пары:?

5. Мероприятие


Условие
На рекламное мероприятие требуется организовать t участков квадратной формы. Есть несколько стен, длин h1, h2, h3 hn

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



Пример разбиения, тут три стены, указаны зеленым, и 6 участков, указаны красным

Входные данные: Строка, разделенная точкой с запятой (";") на 2 части: первое число количество участков t, а далее, список длин всех стен через запятую (",").

Ответ: минимальная площадь
Пример ответа: 15
Тестовые пары:?

6. Поиск подходящих складов


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

Склад размером 2 на k, разделен на ячейки размером 1 на 1, при этом некоторые ячейки свободны и именно это пространство предназначено для складирования бытовой техники. Можно ли поместить пластины, размером 2 на 1 так, чтобы они занимали всё свободное пространство, и при этом не накладывались друг на друга?



Пример с пластинами, где пластины розовые, зеленые, синие.

Входные данные: строка, в которой первое число длина склада k, а остальные символы это пары чисел, разделённые точкой с запятой (";), которые обозначают координаты занятых точек. Координаты между собой разделены запятой (,").

Пример входных данных: 5;2,2;1,4
Выходные данные: 1 если можно, 0 если нет.
Тестовые пары:?

7. Организация консультантов


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

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

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

Если сотрудники новички, то они автоматически направлены направо. Входные данные подобраны так, чтобы можно было найти единственное решение. Пример ниже.



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

Пример входных данных: 0,0,2,1,1,2

Выходные данные: Строка, состоящая из 0 и 1, разделённых запятой, соответствующая входной, в которой 0 если консультант смотрит влево, и 1, если смотри вправо.

Если это невозможно, нужно вывести строку NO.
Пример выходных данных в примере: 1,1,0,0,1,0

Тестовые пары:?

8. Единая команда


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

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



Входные данные: Строка, которая разделена точкой с запятой (";"), в которой первая часть это подстрока t,n, описывающий количество сотрудников t и количество отделов n. Вторая часть подстрока, в которой указано, какой из сотрудников (по порядку) в каком отделе находится (числа разделены запятой). Последующие части пары людей, знакомых друг с другом (порядковые номера сотрудников разделены запятой).

Пример входных данных: 6,3;1,1,2,2,3,3;1,3;1,5;1,6;2,5;2,6;3,4;3,5;5,6

Выходные данные: количество способов выбрать две команды.

Пример ответа: 2
Тестовые пары:?

9. Найдите местоположение


Условие:
Решается вопрос, где оптимально было бы разместить новые магазины бытовой техники. Один из факторов это пути доставки бытовой техники от различных складов. Каждый магазин должен быть расположен в одной из данных вершин, рядом с каким-то складом.

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

Посчитайте количество вершин m на графе.



Пример графа [[2,5,1,1,4],[1,2],[1,3],[2,4],[2,5]], при этом исконные вершины отмечены голубым

Входные данные: Строка, разделённая точкой с запятой (";"), в которой первая часть содержит типы складов по порядку (разделённых запятой). Остальные части являются доступными путями, которые записываются двумя числами (разделёнными запятой), где показывается, между какими складами существует дорога.

Пример входных данных: 2,5,1,1,4;1,2;1,3;2,4;2,5

Выходные данные: количество подходящих вершин m

Пример ответа: 3
Тестовые пары:?

10. Роботизация рекламы


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

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



Пример минимального маршрута, при обходе трех точек.

Входные данные: Строка, содержащая координаты предметов. Каждый предмет разделён точкой с запятой (";"), а каждая координата в нём запятой (",")
Пример входных данных: 1,2;3,4;4,1

Пример ответа: 3
Тестовые пары:?
Подробнее..

Нужен DevOps 6 разряда

23.04.2021 18:05:42 | Автор: admin

Помните, как в начале 2021 года мы планировали дополнительно нанять в штат 600 программистов? Позади три месяца и в нашей команде уже прибавилось +250 крутых разработчиков.

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


Приходите! Будет интересно! GO на борт!

З.. Что такое DevOps 6 разряда? Нам тоже интересно. Скоро расскажем про нашу систему мотивации и грейдов. Stay tuned!
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru