Точка входа в программирование
21.4K subscribers
903 photos
163 videos
1 file
2.45K links
Фундаментальные знания по основам программирования

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels

Сайт: https://tprg.ru/site

Регистрация в перечне РКН: https://tprg.ru/zrgj
Download Telegram
Простыми словами: Что такое абстракция в ООП

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

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

Зачем нужна абстракция?

1. Упрощение взаимодействия: Абстракция упрощает использование сложных систем, предоставляя понятные и удобные интерфейсы.
2. Сокрытие деталей реализации: Позволяет скрывать детали, которые не важны для пользователя объекта.
3. Повторное использование кода: Обеспечивает создание общих интерфейсов, которые могут быть использованы в различных контекстах.

Пример 1: Абстрактные классы

В некоторых языках программирования, таких как Python, Java или C#, существуют абстрактные классы. Они содержат методы, которые должны быть реализованы в дочерних классах.

from abc import ABC, abstractmethod

class Животное(ABC):
@abstractmethod
def издать_звук(self):
pass

class Кот(Животное):
def издать_звук(self):
print("Мяу!")

class Собака(Животное):
def издать_звук(self):
print("Гав!")

животные = [Кот(), Собака()]

for животное in животные:
животное.издать_звук()


Здесь Животное — это абстрактный класс с абстрактным методом издать_звук, который обязаны реализовать все дочерние классы, такие как Кот и Собака.

Пример 2: Интерфейсы (в других языках)

В языках программирования, таких как Java или C#, существуют интерфейсы, которые определяют набор методов, которые должны быть реализованы классами.

interface Животное {
void издатьЗвук();
}

class Кот implements Животное {
public void издатьЗвук() {
System.out.println("Мяу!");
}
}

class Собака implements Животное {
public void издатьЗвук() {
System.out.println("Гав!");
}
}

public class Main {
public static void main(String[] args) {
Животное кот = new Кот();
Животное собака = new Собака();

кот.издатьЗвук(); // Output: Мяу!
собака.издатьЗвук(); // Output: Гав!
}
}


Здесь Животное — это интерфейс, который определяется методом издатьЗвук, что должен быть реализован в классах Кот и Собака.

Давайте теперь посмотрим, где применяется эта концепция в реальной жизни:

1. Управление пользователями. Абстракция позволяет создавать общие интерфейсы для работы с пользователями различных типов — например, администраторы и обычные пользователи.

from abc import ABC, abstractmethod

class Пользователь(ABC):
@abstractmethod
def доступ(self):
pass

class Админ(Пользователь):
def доступ(self):
return "Полный доступ"

class Гость(Пользователь):
def доступ(self):
return "Доступ в режиме чтения"

пользователи = [Админ(), Гость()]
for пользователь in пользователи:
print(пользователь.доступ())


2. Работа с данными. Часто используется, когда нужно создать общий интерфейс для работы с разными источниками данных.

from abc import ABC, abstractmethod

class Репозиторий(ABC):
@abstractmethod
def получить_данные(self):
pass

class SQLРепозиторий(Репозиторий):
def получить_данные(self):
return "Данные из SQL базы данных"

class APIРепозиторий(Репозиторий):
def получить_данные(self):
return "Данные из API"

репозитории = [SQLРепозиторий(), APIРепозиторий()]
for репозиторий in репозитории:
print(репозиторий.получить_данные())


3. Системы оплаты. Можно создать абстракцию для различной обработки платежей — кредитными картами, PayPal, Bitcoin и т.д.

class Платеж(ABC):
@abstractmethod
def провести_платеж(self, сумма):
pass

class КредитнаяКарта(Платеж):
def провести_платеж(self, сумма):
print(f"Платеж проведён на сумму {сумма} с кредитной карты")

class PayPal(Платеж):
def провести_платеж(self, сумма):
print(f"Платеж проведён на сумму {сумма} через PayPal")

платежи = [КредитнаяКарта(), PayPal()]
for платеж in платежи:
платеж.провести_платеж(100)


#простымисловами #ооп
Простыми словами: Инкапсуляция в ООП

Мы с вами уже разобрали наследование и абстракцию. Пришло время третьей парадигмы. Инкапсуляция — это концепция ООП, которая скрывает внутренние детали объекта и предоставляет доступ только к нужным методам и свойствам. Это как капсула с лекарством: вы знаете, как её использовать, но не видите, что внутри.

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

Давайте рассмотрим несколько примеров:

В Python инкапсуляции часто достигают с помощью именования методов и атрибутов с одним или двумя подчёркиваниями.
class Кот:
def __init__(self, имя):
self.__имя = имя # Скрытый атрибут

def получить_имя(self):
return self.__имя # Метод для получения скрытого атрибута

def мяукать(self):
print(f"{self.__имя} говорит: Мяу!")

кот = Кот("Мурзик")
print(кот.получить_имя()) # Output: Мурзик
кот.мяукать() # Output: Мурзик говорит: Мяу!

# Попытка доступа к скрытому атрибуту напрямую
# print(кот.__имя) # Это вызовет ошибку


В этом примере атрибут __имя скрыт от внешнего доступа, и доступ к нему можно получить только через метод получить_имя.

Давайте рассмотрим пример из Java. Здесь инкапсуляция достигается с помощью модификаторов доступа (private, protected, public) и методов getter/setter.
public class Кот {
private String имя; // Скрытый атрибут

public Кот(String имя) {
this.имя = имя;
}

public String getИмя() { // Метод для получения скрытого атрибута
return имя;
}

public void мяукать() {
System.out.println(имя + " говорит: Мяу!");
}

public static void main(String[] args) {
Кот кот = new Кот("Мурзик");
System.out.println(кот.getИмя()); // Output: Мурзик
кот.мяукать(); // Output: Мурзик говорит: Мяу!

// Попытка доступа к скрытому атрибуту напрямую
// System.out.println(кот.имя); // Это вызовет ошибку
}
}


В этом примере атрибут имя объявлен как private и доступен только через метод getИмя.

Где применяется?

Инкапсуляция помогает скрыть детали внутренней структуры объекта, например, банковского счёта.
class БанкСчет:
def __init__(self, баланс=0):
self.__баланс = баланс # Скрытый атрибут

def пополнить(self, сумма):
if сумма > 0:
self.__баланс += сумма

def вывести(self, сумма):
if сумма > 0 и self.__баланс >= сумма:
self.__баланс -= сумма

def получить_баланс(self):
return self.__баланс

счет = БанкСчет()
счет.пополнить(100)
счет.вывести(30)
print(счет.получить_баланс()) # Output: 70


Также позволяет управлять доступом к критическим операциям.
class Пользователь:
def __init__(self, имя, пароль):
self.__имя = имя
self.__пароль = пароль # Скрытый атрибут

def проверить_пароль(self, ввод):
return self.__пароль == ввод

пользователь = Пользователь("Иван", "12345")
print(пользователь.проверить_пароль("12345")) # Output: True
print(пользователь.проверить_пароль("54321")) # Output: False


Теперь вы знакомы с тремя составляющими ООП. Нам осталось разобраться в полиморфизме.

Если формат заходит — поставьте ❤️, я буду знать, что пишу не зря. А замечания можете написать в комментарии👇

#простымисловами #ооп #инкапсуляция
Простыми словами: Полиморфизм в ООП

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

Давайте же разберём подробно концепцию полиморфизма в объектно-ориентированном программировании (ООП) с примерами кода.

Полиморфизм — это концепция ООП, позволяющая использовать один и тот же интерфейс для разных типов объектов. Он позволяет объектам разных классов обрабатывать вызовы методов с одинаковыми именами, предоставляя каждым свой уникальный подход к реализации.

Зачем нужен полиморфизм?

1. Унификация интерфейсов позволяет использовать один интерфейс для взаимодействия с различными типами объектов.
2. Гибкость и расширяемость упрощает добавление нового функционала, так как новые классы могут использовать существующие интерфейсы.
3. Упрощение кода позволяет писать более общий и универсальный код.

Как это выглядит в коде?

В Python полиморфизм часто достигается через методические перегрузки и наследование:
class Животное:
def издать_звук(self):
raise NotImplementedError("Этот метод должен быть реализован в подклассе")

class Кот(Животное):
def издать_звук(self):
print("Мяу!")

class Собака(Животное):
def издать_звук(self):
print("Гав!")

животные = [Кот(), Собака()]

for животное in животные:
животное.издать_звук() # Output: Мяу! Гав!


В этом примере метод издать_звук вызывается для объектов различных классов (Кот и Собака), и каждый объект реализует этот метод по-своему.

В Java полиморфизм достигается через интерфейсы и абстрактные классы:
abstract class Животное {
abstract void издатьЗвук();
}

class Кот extends Животное {
@Override
void издатьЗвук() {
System.out.println("Мяу!");
}
}

class Собака extends Животное {
@Override
void издатьЗвук() {
System.out.println("Гав!");
}
}

public class Main {
public static void main(String[] args) {
Животное[] животные = { new Кот(), new Собака() };

for (Животное животное : животные) {
животное.издатьЗвук(); // Output: Мяу! Гав!
}
}
}


Здесь абстрактный метод издатьЗвук реализуется в классах Кот и Собака, и тот же метод вызывает различные реализации в зависимости от объекта.

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

1. Фигуры

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

class Фигура:
def площадь(self):
raise NotImplementedError("Этот метод должен быть реализован в подклассе")

class Круг(Фигура):
def __init__(self, радиус):
self.радиус = радиус

def площадь(self):
return 3.14159 * self.радиус ** 2

class Прямоугольник(Фигура):
def __init__(self, ширина, высота):
self.ширина = ширина
self.высота = высота

def площадь(self):
return self.ширина * self.высота

фигуры = [Круг(5), Прямоугольник(3, 4)]

for фигура in фигуры:
print(f"Площадь: {фигура.площадь()}")


2. Платежные системы

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

class Платеж(ABC):
@abstractmethod
def провести_платеж(self, сумма):
pass

class КредитнаяКарта(Платеж):
def провести_платеж(self, сумма):
print(f"Платеж проведён на сумму {сумма} с кредитной карты")

class PayPal(Платеж):
def провести_платеж(self, сумма):
print(f"Платеж проведён на сумму {сумма} через PayPal")

платежи = [КредитнаяКарта(), PayPal()]
for платеж in платежи:
платеж.провести_платеж(100)


Полиморфизм — ключевая концепция ООП. Он делает ваш код более универсальным и удобным для использования и расширения. Это особенно полезно, когда ваш проект растёт и требует поддержки различных типов объектов.

#простымисловами #ооп #полиморфизм
Простыми словами: Зерокодинг

Многие хотят в IT, но не всех привлекает написание кода. Таким людям можно попробовать себя в зерокодинге.

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

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

Сегодня профессии, связанные с зерокодингом, становятся всё более популярными. Зерокодеры работают с различными платформами: создают сайты на Tilda и Webflow, сборки опросов на Typeform, и даже приложения на Glide или Adalo. Их задача — понять, какие задачи нужно решить, и выбрать подходящий инструмент для этого.

Давайте немного поговорим о том, сколько такие специалисты могут зарабатывать.

Доход зерокодеров в России может варьироваться в зависимости от их навыков и опыта. В среднем, как показывает практика, начинающие могут зарабатывать от 50 000 до 80 000 рублей в месяц. Более опытные специалисты, которые могут интегрировать сложные составляющие и автоматизировать бизнес-процессы, могут получать от 100 000 рублей и выше.

Разумеется зерокодинг имеет свои плюсы и минусы, поэтому стоит учитывать их, если решите попробовать себя в этом направлении.

Плюсы:

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

Минусы:

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

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

А вы хотели бы попробовать себя в этом?

🗿 — только код, только хардкор
❤️ — выглядит интересно и не так сложно, как обычное программирование. Я бы попробовал
🤔 — а можно просто денег и не работать
?

#простымисловами #зерокодинг
Простыми словами: Какие стили программирования существуют

Кроме объектно-ориентированного программирования (ООП), существует несколько других видов программирования, каждое из которых применяется в различных областях и имеет свои особенности.

1. Процедурное программирование

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

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

Минусы:
— сложность управления большими проектами;
— меньшая гибкость и повторное использование кода по сравнению с ООП.

Такой стиль можно встретить в системном программировании, встраиваемых системах и приложениях с простой структурой.

2. Функциональное программирование

Оно используется для работы с вычислениями, которые можно описать как набор математических функций. В таком стиле часто пишут на Haskell, Lisp, Erlang, Scala, и даже JavaScript.

Плюсы:
— выраженная математическая чистота и вероятностное отсутствие побочных эффектов;
— лёгкость тестирования и отладки.

Минусы:
— меньшая распространённость и сложность освоения для новичков;
— ограниченность инструментов и библиотек в сравнении с ООП.

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

3. Логическое программирование

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

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

Минусы:
— сложность понимания и отладки;
— ограниченные области практического применения.

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

4. Декларативное программирование

Используется для описания желаемого результата, а не шага к его достижению. Используется в SQL (для запросов к базам данных), HTML (для веб-разметки), XSLT (для трансформации XML).

Плюсы:
— ясность и простота синтаксиса;
— фокус на описании задачи, а не способе её решения.

Минусы:
— ограниченность в универсальности решения задач;
— зависимость от конкретных исполнительных сред.

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

5. Мультипарадигменное программирование

Этот стиль предполагает объединение нескольких парадигм программирования (например, ООП и функционального программирования) в одном языке или приложении. Может быть реализовано на многих языках, включая Python, JavaScript, Kotlin, Scala, Swift и т.д.

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

Минусы:
— потенциальная сложность освоения всего спектра возможностей языка;
— возможность несогласованных паттернов кода.

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

Какая парадигма сейчас более популярна?

Сегодня сложилось так, что объектно-ориентированное программирование остаётся одной из самых популярных парадигм, особенно в разработке крупных и сложных систем. Однако функциональное программирование набирает обороты, особенно в области обработки данных и параллельных вычислений. Мультипарадигменные языки, такие как Python и JavaScript, также стали очень популярны благодаря своей гибкости и широким возможностям.

Каждая парадигма имеет свои сильные и слабые стороны и находит свое применение в различных областях. Выбор подходящей парадигмы зависит от конкретной задачи и требований проекта.

🤯 — не знал, что их так много
🤔 — а можно теперь подробнее про каждую?
❤️ — зачем что-то придумывать, если есть ООП?


#простымисловами
Простыми словами: Процедурное программирование

В прошлом посте рубрики я вкратце рассказал про разные парадигмы программирования. Пришло время углубится в одну из них

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

#простымисловами #парадигмыпрограммирования
Точка входа в программирование
Простыми словами: Процедурное программирование В прошлом посте рубрики я вкратце рассказал про разные парадигмы программирования. Пришло время углубится в одну из них Процедурное программирование остаётся важной парадигмой, особенно в областях, где требуется…
Простыми словами: Функциональное программирование

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

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

#простымисловами
Forwarded from Zen of Python
Простыми словами: Паттерн «Одиночка»

Про «Фасад» поговорили. Теперь расскажу про другой популярный паттерн.

«Одиночка» (Singleton) полезен, когда необходимо гарантировать существование единственного экземпляра объекта в системе. Но использовать его следует с осторожностью. Хотя он полезен для управления ресурсами и обеспечения согласованности данных, это может привести к сложностям при тестировании и многопоточности. Каждое использование Singleton должно быть тщательно обосновано, чтобы избежать потенциальных проблем и антипаттернов.

#простымисловами #паттерны
Точка входа в программирование
Простыми словами: Функциональное программирование Про процедурное программирование мы уже рассказали. Теперь поговорим о функциональном. Функциональное программирование — мощный и полезный инструмент, особенно для задач, где важны надёжность и предсказуемость.…
Простыми словами: Логическое программирование

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

Логическое программирование — мощный инструмент для задач, требующих логического вывода и анализа. Оно предоставляет декларативный подход к решению задач, работая с фактами и правилами. Несмотря на ограничения, оно незаменимо в областях, где требуется высокая степень абстракции и интеллектуальный анализ.

🤯 — никогда не слышал про такое
❤️ — хочу писать на Prolog


#простымисловами
Точка входа в программирование
Простыми словами: Логическое программирование Продолжаем тему парадигм программирования. В прошлый раз говорили про известное многим функциональное программирование. Теперь же поговорим про то, о чем многие не слышали. Логическое программирование — мощный…
Простыми словами: Декларативное программирование

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

❤️ — если использовал декларативное программирование

#простымисловами
Точка входа в программирование
Простыми словами: Декларативное программирование Декларативное программирование — это подход, ориентированный на результат, который позволяет сосредотачиваться на целях, а не на способах их достижения. Оно упрощает разработку и поддержку кода, однако может…
Простыми словами: Мультипарадигменное программирование

Следующее на очереди после декларативного программирования у нас программирование, которое объединяет в себе сразу несколько парадигм. Оно позволяет использовать их сильные стороны, обеспечивая гибкость и расширяемость кода. Этот подход особенно подходит для сложных проектов, где разные задачи требуют разных решений. Однако разработчики должны быть внимательны, чтобы избежать чрезмерного усложнения и сохранить читаемость кода.

#простымисловами #парадигмы
Точка входа в программирование
Простыми словами: Паттерн «Одиночка» Про «Фасад» поговорили. Теперь расскажу про другой популярный паттерн. «Одиночка» (Singleton) полезен, когда необходимо гарантировать существование единственного экземпляра объекта в системе. Но использовать его следует…
Простыми словами Паттерн «Factory Method»

Продолжаем тему паттернов. Паттерн Factory Method упрощает создание различных объектов, избегая прямой зависимости от их классов. Он особенно полезен, когда вы работаете с семействами похожих объектов, которые могут изменяться или добавляться. Это повышает гибкость и делает проект более масштабируемым.

Подробнее о нём можно узнать в карточках.

#простымисловами #паттерны
#простымисловами: ​​Различия между MVC, MVP, MVVM, MVVM-C, и VIPER

Эти архитектурные паттерны являются одними из наиболее часто используемых при разработке приложений, как на платформах iOS, так и Android.

MVC (Model-View-Controller) — один из самых широко используемых архитектурных шаблонов. Он разделяет приложение на три основных компонента: модель (представляет данные и бизнес-логику), представление (отвечает за отображение интерфейса) и контроллер (действует как посредник между моделью и представлением).

MVP (Model-View-Presenter) отчасти похож на MVC, но имеет немного другой подход. В MVP посредником между моделью и представлением является презентер , а не контроллер. Презентер отвечает за обновление представления данными из модели и обработку пользовательского ввода и событий.

MVVM (Model-View-ViewModel) — архитектурный шаблон, набирающий популярность и используемый в приложениях со сложными пользовательскими интерфейсами. Он похож на MVP, но с добавлением модели представления (view model), которая отвечает за управление состоянием представления и за предоставление данных из модели в представление.

MVVM-C (Model-View-ViewModel-Coordinator) — это вариация MVVM, с добавлением координатора, который отвечает за управление навигацией между различными экранами или представлениями в приложении. Этот шаблон полезен для приложений, в которых есть несколько управляемых экранов или представлений.

VIPER (View-Interactor-Presenter-Entity-Router) — относительно новая архитектурный шаблон, который похож на MVC, но с добавлением нескольких новых компонентов, включая интерактор (отвечает за обработку бизнес-логики), сущность (представляет данные) и маршрутизатор (обрабатывает навигацию между различными экранами и представлениями).

#паттерны
#простымисловами: Паттерн Observer (Наблюдатель)

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

Подробнее в карточках.