This note is the result of the effort of the civil engineering major, the engineer, the nose, the water, and the writing. The finger picking is not a Masakari, but a pure white Taoru, which is also excellent and thrown.
I said, "No, but I've written Pyhton for a long time, and I wonder if I've completely understood Python!"
I said, "Would you like to see it in docs.python.org after a long time? If you look at it now, you can see everything www"
I "Functional Programming HOWTO ...? What's that ..."
I said, "Well ...? Most programming languages are ** procedural ** ?, and an instruction list that teaches the computer what to do with input? ** Object-oriented **? Manipulates a collection of objects. Has an internal state, and there is a method to check and change that state ...? ** Function type **? Just divides the problem into several functions, waits for input, and spits out output. Doesn't it have any internal state that spits different outputs for the same input? "
I "?????????"
I "Um ...?"
Python is such a multi-paradigm language. You can use any of these to write programs and libraries that are basically procedural, basically object-oriented, or basically functional. In large programs, each part may be written using a different approach, GUI is object-oriented, but processing logic is procedural or functional, and so on.
I "What do you want to say after all ... I don't know anything ..."
I said, "There are various ** methods ** and ** features ** in programming in the first place."
Method | Feature | Typical language |
---|---|---|
Procedural | A style in which procedures (functions, etc.) that combine instructions are described and combined. | C |
Functional type | A style of constructing a program from the composition and application of functions. | Haskell |
Object-orientation | A style that considers the data to be handled and the operation procedure as a group. | Java |
I said, "Hmm ... I don't know ... What's the difference between procedural type and functional type? Let's investigate a little more."
――Write down the method to solve the problem in detail according to the procedure --The procedure can be described one by one from the top, but in general, multiple functions are defined and they are combined to change the data. --Simple and easy to understand the process flow (easy to see and write) --Typical languages: C, etc.
I said, "I see. The point is to write the processing in order from the top like this. This is what I finally do with Python."
def add(x, y):
return x + y
def squared(x):
return x ** 2
squared_x = squared(2) # 4
squared_y = squared(4) # 16
add_xy = add(squared_x, squared_y) # 20
I "Hona, next"
--Variables and functions are referentially transparent and side effects are suppressed or completely eliminated.
――In other words, the inside of the function does not rely on any external data and does not change them.
--In a pure functional type with side effects completely eliminated, there is no idea of assigning a value to a variable, and the value is bound
to the variable.
--Pipelines, higher-order functions, closures, etc. are used to divide the processing into functions and use them in combination.
--Typical languages: Haskell, etc.
I said, "Hmm ??? A difficult word came out ..."
I said, "Once you define x = 1
, it is guaranteed that x is 1 in the program. "
I said, "I can't say the same thing with functions. It's like mathematics that always returns the same value. When I started programming,"
x = x + 1
I said, "I was almost upset when I saw it. The right side and the left side are not equal."
I said "... well, I see. Python is a concept that seems difficult to apply because most variables are variable, but I'd appreciate it if the return value is constant. It's easy to test. What are the side effects?"
I said, "Ah, yes, I see. I fully understand."
I said, "But how do you program by completely eliminating the state of reassignment ...? For statements are used, but Python for statements do not create a local scope and are typical examples of side effects ..."
I said "Yes !!!!!! Use the built-in function map
!!!!!! "
#Procedural
def squared(x):
return x ** 2
number_list = [1, 2, 3, 4, 5]
squared_list = [] # [1, 4, 9, 16, 25]
for n in number_list:
squared_list.append(squared(n))
#Functional type
squared_list = list(map(lambda x: x ** 2, [1, 2, 3, 4, 5])) # [1, 4, 9, 16, 25]
I said, "I was able to write on one line without changing the state. Isn't it amazing?"
I said, "However, there is no doubt that the procedural code is more intuitive and easy to understand ... The point is, think about where to use it."
I "What's next?"
--Higher-order function: A function that takes a function as an argument (also called a callback function) --Closer: A function whose nested internal function remembers the variables defined by the parent function.
I said, "The map
I used earlier receives a lambda expression (anonymous function)
, so it's a typical example of a higher-order function."
I said, "By making it possible to receive a function, it is not necessary to write specific processing in one function, so it is easy to divide the processing, that is, it is more extensible."
I said, "Also, if you receive a function, you can easily put a fixed process before and after the received function, and you can add a function without affecting the main process! It seems that this is called a decorator in Python. ! "
#Measure the processing time of a function
from functools import wraps
import time
#Define a function that receives a function
#Return the internal function
def time_measurement(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
exe = func(*args, **kwargs)
end = time.time()
print(f"time_measurement: {end - start}")
return exe
return wrapper
# @When called with (decorator), it enters the argument of the called function.
@time_measurement
def func(num):
res = 0
for n in range(num):
res += n
return res
func(10000000) # time_measurement: 0.48942112922668457
I said, "It seems that a function that is nested like the one below and remembers variables defined outside is called a closure!"
#Enclosure
def outer():
x = 1
#closure
def inner(y):
return x + y
return inner
f = outer() #The return value is inner()
i = f(10) #Since inner is executed, the return value will be 11.
I said, "However, you can refer to the variable defined by the parent, but you can't update it without declaring a special statement called nonlocal
, so be careful! "
I said, "Functional programming is the same as programming using functions, but considering maintainability and extensibility, it is a good idea to use the full power of the language to create a program that has no side effects (as much as possible). "
I said, "Is it object-oriented at the end? It's a guy who is often compared to apples or cars!"
--A method to allow the system to respond flexibly to changes by extracting the parts that will change frequently into classes. --In object-oriented programming, unlike functional type, it has a state inside, and a program is created by referring to and changing it. --Hide it internally by allowing changes only from the methods (behaviors) defined in the interface in order to suppress the occurrence of side effects. --Having features such as concealment / abstraction / inheritance / diversity --Typical languages: C ++, Java, etc.
I said, "I see. The point is that it's a'class`. I don't want to program by considering the structure and behavior of data as one thing."
I "Although it allows states to exist unlike functional types, hiding them inside prevents bugs from occurring."
I said, "I don't know if there are too many keywords ... Check them out one by one."
--By changing all the properties of the instance through the method, it is possible to prevent the illegal property from being changed directly from the outside. ――The important thing is "correct naming" because it is easier to encapsulate by unifying the roles of the class. Good naming means that it is simple and has a clear purpose, so it is easy to hide.
I said, "Hmm. You can't mess with the variables of the instance created from the class directly."
I said, "But Python can't define variables that can't be changed, so if you do it, it's like this?"
--Use @ property and @ property.setter in python --Add an underscore at the beginning of the variable for properties that you do not want to access from the outside --However, since python cannot create private variables that are really inaccessible, it is customary to say "don't access".
I said, "First of all, let's make a meat class whose price changes according to the weight."
class Meat:
#Instance initialization
#Each instance has the attributes defined here
def __init__(self, name, weight):
if weight < 0:
raise ValueError("Weight should not be less than 0g")
self.name = name
self.weight = weight
#Not to be used directly from the outside_Put on
#Discount is set to the initial value of 5
self._unit_price = 5
self._price = 0
#Set the string to be displayed when calling the instance
def __repr__(self):
return f"{self.name}: {self.price}Circle"
#By attaching a property decorator, you can call a method like an instance variable from the outside.
@property
def unit_price(self):
#Set the value you want to refer to as the return value
return self._unit_price
@property
def price(self):
return self.weight * self._unit_price
#Use setter to change variables
#When you want to change a variable, do not overwrite it directly, but overwrite it through a method
#By doing this, external references will be made through this method, preventing incorrect values from being mixed in.
@unit_price.setter
def unit_price(self, value):
if not (1 <= value <= 10):
raise ValueError("Please set the unit price between 1 yen and 10 yen")
self._unit_price = int(value)
I said, "OK, try using it right away."
>>> meat = Meat("Matsusaka beef", 200)
>>> meat
Matsusaka beef:1000 yen
>>> meat.unit_price = 100
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 30, in unit_price
ValueError:Please set the unit price between 1 yen and 10 yen
>>> meat.unit_price = 10
>>> meat
Matsusaka beef:2000 yen
>>> meat.price = 3000
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: can't set attribute
I said, "Matsusaka beef is expensive. I want to eat full."
I said, "But it works as expected. Now I can implement it as follows."
--name
and weight
can be set as initial values
--When you call the object, name: price circle
is displayed.
--price
is calculated automatically
--ʻUnit_pricegives an error when trying to set a value outside the range --Error when trying to set a value directly to
price`
I said, "If you think about it, calculating the amount from the weight is a process peculiar to meat."
I said, "Let's change the class name to Item. The price does not always change depending on the weight, and the unit price may be fixed and only the number may change. Okay, once the unit price setting is removed . "
I said, "I don't think this is an abstraction."
--Collect the parts that will change frequently and extract only the essential features into the class. ――When you can express "A is B", they should be summarized more abstractly. ――The concept of abstraction is to summarize common points as a standard in order to make replaceable parts. —— Strong against changes, but be careful not to overdo it
class Item:
def __init__(self, name):
self.name = name
self._price = 0
def __repr__(self):
return f"{self.name}: {self.price}Circle"
@property
def price(self):
return self._price
I said, "When I want to make a meat class again, I'll make a concrete class byinheriting
the above abstract class (Item class)."
--Creating a more concrete class by inheriting the parent abstracted object --If it is python, it can be inherited by taking the parent class as an argument when defining the class. --The properties and methods of the parent class cannot be used unless they are explicitly inherited by using the super () method at the time of initialization.
class Meat(Item):
def __init__(self, name, weight):
# super()Explicitly using the parent class__init__()Call
super().__init__(name)
self.weight = weight
self._unit_price = 5
@property
def unit_price(self):
return self._unit_price
#Override method
@property
def price(self):
return self.weight * self._unit_price
@unit_price.setter
def unit_price(self, value):
if not (1 <= value <= 10):
raise ValueError("Please set the unit price between 1 yen and 10 yen")
self._unit_price = int(value)
>>> meat = Meat("Matsusaka beef", 500)
>>> meat
Matsusaka beef:2500 Yen
>>> meat.unit_price = 100
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 21, in unit_price
ValueError:Please set the unit price between 1 yen and 10 yen
>>> meat.unit_price = 10
>>> meat
Matsusaka beef:5000 Yen
>>> meat.price = 3000
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: can't set attribute
I said, "I want to make an apple class and a mandarin orange class with this !!!!"
I said, "By the way, I created an abstract class as a class this time, but usually it seems that only thebehavior (method name)
is defined in the interface."
I "Do not write the contents of the method in the interface, and leave the concrete implementation to the inherited class (forced implementation of the method)."
I said, "By doing so, it will be confirmed that all the inherited classes have methods with the same name, so the outlook will be better! It seems that this is calledpolymorphism
!!"
――Programming for abstracted classes so that they can be used in various ways ――In other words, even though the functions and methods have the same name, they behave differently according to the type.
I said, "Huh. I finally understood the characteristics of the writing style. All of them are wonderful."
I said, "Procedural programming makes it easy and quick to write clear code. However, if you are medium-sized or larger, you can go straight to spaghetti ..."
I said, "It seems difficult to write a functional type, but in large-scale development, it seems to be extensible because it is separated into reusable parts, and it seems that there will be fewer bugs."
I said, "Object-oriented programming seems to be strong on a large scale. It seems difficult, but if you can abstract it well, the amount of code will decrease as a result!"
I said, "By the way, Python has side effects, but it's a versatile language that can be programmed even with functional programming and can be object-oriented! It seems to be a multi-paradigm language!"
I said, "That's why you should learn the method well and use it correctly! Do your best to fully understand Python!"
Oshimai
Recommended Posts