View difference between Paste ID: 5HW57Tcp and PkfJ9wm1
SHOW: | | - or go back to the newest paste.
1
# INHERITANCE - Наследяване
2
Този принцип позволява създаването на нови класове, които наследяват поведението(атрибути и методи) от вече съществуващи класове.
3
Както и може да го променим/разширим според нашите нужди.
4
5
Класът, който предава своите атрибути и методи,
6
се нарича -"Parent"=="родителски клас" (също наричан "Super"=="супер клас" или "Base"=="базов клас"),
7
8
а класът, който наследява тези атрибути и методи,
9
се нарича "Child"=="детски клас" (също наричан "Derived"=="потомък"=="производен клас").
10
11
Многожествено наследяване може да се постигне с Mixins.
12
13
===================================================================================================================================
14
# "ENCAPSULATION" - Инкапсулация
15
Принцип, който се отнася до скриването на детайли от реализацията на един обект и предоставянето на публичен интерфейс, чрез който други обекти могат да взаимодействат с него. Този принцип цели да улесни управлението на сложността на кода и да предпази данните и функционалността на обекта от неправилни манипулации.
16
17
 - PROTECTED (защитен): "_protected_this_func"
18
        Те не са предназначени да бъдат използвани извън класа, но все още са достъпни отвън.
19
        
20
- PRIVATE (частен): "__private_this_func"
21
    Считат за частни. Те са много ограничени и не могат да бъдат достъпвани директно отвън на класа.
22
    
23
Въпреки това може да се достъпи по този "tricky" начин:
24
    Instance = Class()
25
	print(instance._Class__variable)
26
27
"Getters" и "setters" се използват за четене и записване на стойности на атрибути на обект.
28
Тези методи позволяват контролиран достъп до атрибути и допълнителна логика при четене или записване на стойности.
29
Този подход подобрява инкапсулацията на данните и улеснява поддръжката на кода.
30
В Python този модел на четене и записване се реализира със специални методи,
31
известни като "property" и "setter"
32
33
===================================================================================================================================
34
# "POLYMORPHISM" - Полиморфизъм
35
Способността на обекти от различни класове да бъдат третирани като обекти на общ родителски клас.
36
Това позволява да се извършват общи операции над обекти от различни типове, без да е необходимо да се знае точно какъв тип е всеки обект.Полиморфизмът предоставя гъвкавост и улеснява разширяването на системата.
37
38
class Animal:
39
    def speak(self):
40
        pass
41
42
class Dog(Animal):
43
    def speak(self):
44
        return "Woof!"
45
46
class Cat(Animal):
47
    def speak(self):
48
        return "Meow!"
49
    
50
# Функция, която приема обекти от тип Animal и извиква метода speak()
51
def animal_sound(animal):
52
    return animal.speak()
53
54
# Извикване на функцията animal_sound с обекти от различни типове
55
dog = Dog()
56
cat = Cat()
57
print(animal_sound(dog))  # Изход: Woof!
58
print(animal_sound(cat))  # Изход: Meow!
59
   
60
===================================================================================================================================
61
# "ABSTACTION" - Абстракция
62
Отнася се до създаването на абстрактни класове, които дефинират общи характеристики и методи, но оставят детайлите на реализацията на конкретните подкласове. Абстракцията позволява скриване на детайлите и фокусиране върху същността на обектите.
63
Дончо - "Абстракцията е да изпълниш дадена работа, без да кажеш, как точно я вършиш."
64
65
from abc import ABC, abstractmethod
66
67
# Абстрактен клас
68
class Shape(ABC):
69
    @abstractmethod
70
    def area(self):
71
        pass
72
73
# Конкретни класове, които наследяват абстрактния клас и реализират метода area()
74
class Circle(Shape):
75
    def __init__(self, radius):
76
        self.radius = radius
77
78
    def area(self):
79
        return 3.14 * self.radius * self.radius
80
81
class Square(Shape):
82
    def __init__(self, side):
83
        self.side = side
84
85
    def area(self):
86
        return self.side * self.side
87
88
# Използване на абстрактния клас и неговите конкретни имплементации
89
circle = Circle(5)
90
square = Square(4)
91
92
print(circle.area())  # Изход: 78.5
93
print(square.area())  # Изход: 16
94
95
===================================================================================================================================
96
97
Всички методи и принципи, които споменахме - наследяване (inheritance), инкапсулация (encapsulation), полиморфизъм (polymorphism) и абстракция (abstraction) - са ключови концепции на обектно-ориентираното програмиране (ООП) и често се използват заедно за създаване на структуриран, лесно разбираем и поддръжаем код.
98
Ето как се свързват тези концепции:
99
    
100
	#Наследяване (Inheritance):
101
Наследяването ни позволява да създаваме нови класове, които наследяват атрибути и методи от вече съществуващи класове.
102
Това спомага за преизползването на код и организацията на кода във вид на хиерархия.
103
Взаимодействието между различни класове създава възможност за полиморфизъм.
104
Класовете могат да се третират като обекти на общ родителски клас, 
105
което позволява извикването на методи от същия интерфейс, независимо от реалния тип на обекта.
106
107
	#Инкапсулация (Encapsulation):
108
Инкапсулацията ни позволява да скриваме детайлите на реализацията на класове и да предоставяме публични методи (интерфейс) за взаимодействие с тези класове. Това подобрява инкапсулацията на данните и прави кода по-чист и лесно поддържаем.
109
Методите "getter" и "setter" са честа форма на инкапсулация, като те позволяват контролиран достъп до атрибутите на класовете.
110
111
	#Полиморфизъм (Polymorphism):
112
Полиморфизмът се основава на наследяването и позволява обекти от различни типове да се третират като обекти на общ родителски клас. Това улеснява извършването на операции върху тези обекти, дори когато те имат различни реализации.
113
Полиморфизмът подчертава гъвкавостта на кода и се използва за обработка на множество обекти с общ интерфейс по един и същи начин.
114
115
	#Абстракция (Abstraction):
116
Абстракцията се използва за определяне на общи интерфейси и характеристики, 
117
които отделят същността на обектите от техните детайли на реализация.
118
Полиморфизмът и абстракцията си взаимодействат, тъй като полиморфизмът ни позволява да използваме абстрактни класове или интерфейси за обработка на множество конкретни обекти. Това намалява зависимостта от конкретни реализации и улеснява поддръжката на кода.
119
===================================================================================================================================
120
121
122
***********************************************************************************************************************
123
# SOLID-Principles:
124
125
# 1. Single responsibility:
126
    Един клас или функция, трябва да бъде отговорен само за една специфична функция/действие
127
    и трябва да има само една причина да бъде променян.
128
    
129
# 2. Open/Closed:
130
    Един клас трябва да бъде отворен за екстендване(разширяване),
131
    но затворен за променянепо-този начин си подсигуряваме работещ код, който не изисква рефакториране.
132
    Това означава, че трябва да можем да добавяме нова функционалност, без да променяме съществуващия код.
133
    "Open for extend, but closed for modifications"
134
135
# 3. Liskov substitution:
136
    Обекти от суперкласа трябва да могат да бъдат заменени с обекти от неговите подкласове,
137
    без да се нарушава коректността на програмата.
138
    Усещаме се, че нарушаваме принципа, като имаме методи в класа, които реално той не може/не трябва да има
139
140
# 4. Interface Segregation:    
141
    Клиентите не бива да са зависими от методи, които не използват. 
142
    Постига се чрез разделянето на големи интерфейси на по-малки и специфични(чрез "Mixins").
143
144
# 5. Dependency inversion:
145
    Бащиният клас трябва да не знае нищо за класа, който го наследява.
146
    Детайлите зависят на абстракцията, а не абстракцията на детайлите.
147
    # 5.1 Dependency Injection - подчаст на Dependency Inversion:
148
		Инжектираме готова инстанция в класа.
149
        Въпрос на контекст е дали в метод или инит.
150
151
***********************************************************************************************************************    
152
    
153
    
154
155
# LISTS as STACKS and QUEUES:
156
1. Stack = LIFO(LAST in FIRST out) 
157
158
2. Queue = FIFO(FIRST in FIRST out) 
159
- "ADD at index[0]" - my_queue.appendleft()
160
- "REMOVE at index[0]" - my_queue.popleft()
161
----------------------------------------------------------------------------
162
Queues in Python are FASTER then LISTS when getting item by index?
163
# False!
164
----------------------------------------------------------------------------
165
Queues in Python are FASTER then LISTS when popping elements from the start? 
166
# True!
167
----------------------------------------------------------------------------
168
What is the structure that stands behind the deque in Python?
169
# Linked lists!
170
171
172
173
# TUPLES:
174
Tuple 'n_tuple' with a list as one of its item.
175
n_tuple = (1, 1, [3,4])
176
177
Items with same value have the same id.
178
id(n_tuple[0]) == id(n_tuple[1])
179
# True
180
Items with different value have different id.
181
id(n_tuple[0]) == id(n_tuple[2])
182
# False
183
------------------------------------------------------------------------------
184
# Combining two tuples to form a new tuple
185
x = (1,2,3,4)
186
y = (5,6,7,8)
187
188
z = x + y 
189
190
z = (1, 2, 3, 4, 5, 6, 7, 8)
191
------------------------------------------------------------------------------
192
# The multiplication operation simply leads to repetition of the tuple.
193
x = (1,2,3,4)
194
z = x*2
195
z = (1, 2, 3, 4, 1, 2, 3, 4)
196
197
198
199
200
# SETS:
201
https://i.pinimg.com/originals/92/74/49/927449ed2c05f7cabe41d12d0db4c0ac.png
202
Sets operations:
203
	-UNION
204
    -INTERSECTION
205
    -DIFFERENCE
206
    -SYMETRIC DIFFERENCE
207
------------------------------------------------------------------------------
208
emptySet = set()  	emptyDict = dict()
209
					emptyDict = {}
210
------------------------------------------------------------------------------
211
Add:						Remove:
212
# mySet.add('example')      # mySet.remove('example')
213
							(if 'example' not in your set -> KeyError!)
214
215
It is important to note that the method raises a KeyError! if the set is empty.
216
You can use the clear method to remove all values from a set -> mySet.clear()
217
218
# Initialize 3 sets
219
set1 = set([1, 2, 3])
220
set2 = set([10, 20, 30])
221
set3 = {'a', 'b', 'c'}
222
223
set1.update(set2)
224
set1 = {1, 2, 3, 10, 20, 30}
225
set1.update(set3)
226
set1 = {1, 2, 3, 10, 20, 30, 'a', 'b', 'c'}
227