> 2021年11月16日信息消化 ### Exploring Polymorphism in Python origin: [Exploring Polymorphism in Python](https://betterprogramming.pub/exploring-polymorphism-in-python-f12b167c5e9f) Polymorphism is quite a famous and interesting topic in programming. As a word, it means occurring in several different forms. In programming, it can be termed as a function or combination of functions having the same name but different functionality. 多态性是编程中一个相当著名和有趣的话题。作为一个词,它意味着以几种不同的形式出现。在编程中,它可以被称为具有相同名称但不同功能的函数或函数组合。 Polymorphism can be broadly categorized into two types: #### Inbuilt Polymorphic Functions These are the built-in operators or functions that can be used in different ways. In the code snippet below, we can see how the addition operator can be used to add two integers, concatenate two strings, and add two lists as well. Similarly, we can see how the built-in function len() can be used to detect length of a string and lists too. 这些是内置的运算符或函数,可以用不同的方式使用。在下面的代码片段中,我们可以看到加法运算符如何被用来添加两个整数、串联两个字符串,以及添加两个列表。同样,我们可以看到内置函数len()也可以用来检测字符串和列表的长度。 ```python print("Output") print("Poly" + " " + "Morphism") print(5 + 6) print(["Poly", 2, "3"] + ["4", 5, "Morphism"]) print(len("PolyMorphism")) print(len([1, 2, 3, 4, 5, 6])) ``` #### User-Defined Polymorphic Functions These, as the name suggests, are the functions that are defined or written by a user to perform different functionalities. In the code snippet below, we can use the multiply function to multiply two numbers, three numbers, or four numbers. We can modify this function according to our needs, and thus it can serve us in multiple ways. 顾名思义,这些都是由用户定义或编写的函数,用于执行不同的功能。在下面的代码片断中,我们可以使用乘法函数将两个数字、三个数字或四个数字相乘。我们可以根据自己的需要修改这个函数,因此它可以在多个方面为我们服务。 ```python def multiply(num1, num2, num3=1, num4=1): return num1 * num2 * num3 * num4 print("Output") final_mul = multiply(2, 3) print(final_mul) final_mul = multiply(2, 3, 4) print(final_mul) final_mul = multiply(2, 3, 4, 5) print(final_mul) ``` #### How To Use Polymorphism? ![Various uses of Polymorphism](https://miro.medium.com/max/1202/1*qYoWTcncdmYIx8GNQLVS8w.png) ##### Operator overloading In this type of overloading, we can use operators in various manners past its predefined meaning, like a multiply operator which can be used to multiply two integers or expand a string. Let’s see a practical implementation of operator overloading: ```python class Books: def __init__(self, price): self.mrp = price def __add__(self, book): return self.mrp + book.mrp maths = Books(250) science = Books(300) print("Total Cost:", (maths + science)) ``` In this example, we are trying to use Books class to store MRP of book and then finding the Total cost and `__add__` function helps us in achieving that. If we don’t include the `__add__` function, we will get an error where we won’t be able to add two objects. So, operator overloading will help us in adding two or more objects depending upon the functionality of `__add__` function here. 在这个例子中,我们试图使用Books类来存储图书的MRP,然后找到总成本,__add__函数帮助我们实现这个目标。如果我们不包含__add__函数,我们将得到一个错误,我们将不能添加两个对象。所以,运算符重载将帮助我们添加两个或更多的对象,这取决于这里的__add__函数的功能。 #### Method overriding In Python, we can reimplement a method and change its functionality in child class according to our needs. We can inherit methods in the child class from the parent class that have the same name, maybe the same parameters but differ in functionality. This process is known as Method Overriding and is very beneficial in case our parent class method’s functionality is not suitable in child class. 在Python中,我们可以根据自己的需要重新实现一个方法,并在子类中改变其功能。我们可以在子类中继承父类中的方法,这些方法有相同的名称,也许有相同的参数,但功能不同。这个过程被称为 "方法覆盖",在父类方法的功能不适合子类的情况下是非常有益的。 ```python class Mercury: def weight(self, w): print(w * 0.38) class Mars(Mercury): def weight(self, w): print(w * 0.38) class Earth(Mars): def weight(self, w): print(w) obj = Mercury() obj.weight(50) obj = Mars() obj.weight(50) obj = Earth() obj.weight(50) ``` #### Duck typing It is derived from the following quote: > “If it looks like a duck and quacks like a duck, it’s a duck.” It means the Class which defined the methods is not important rather than the method it defines. We don’t check types at all in this functionality, we check for the methods and their definition instead. We can understand it with an example similar to method overriding: 这意味着定义方法的类并不重要,而是它所定义的方法。在这个功能中,我们根本不检查类型,而是检查方法和它们的定义。我们可以用一个类似于方法覆盖的例子来理解它: ```python class Mercury: def weight(self, w): print(w * 0.38) class Mars: def weight(self, w): print(w * 0.38) class Earth: def weight(self, w): print(w) for obj in Mercury(), Earth(), Mars(): obj.weight(50) ``` ### Daily Coding Problem #258 This problem was asked by Morgan Stanley. In Ancient Greece, it was common to write text with the first line going left to right, the second line going right to left, and continuing to go back and forth. This style was called "boustrophedon". Given a binary tree, write an algorithm to print the nodes in boustrophedon order. For example, given the following tree: ```p 1 / \ 2 3 / \ / \ 4 5 6 7 ``` You should return [1, 3, 2, 4, 5, 6, 7]. ```python class Node: def __init__(self, val): self.val = val self.ln = None self.rn = None def __repr__(self): return "Node=({}, ln={}, rn={})".format( self.val, self.ln, self.rn) def get_bfs_alt(root, level, level_dict): if not root: return if level not in level_dict: level_dict[level] = list() level_dict[level].append(root.val) get_bfs_alt(root.ln, level + 1, level_dict) get_bfs_alt(root.rn, level + 1, level_dict) def get_boustrophedon(root): level_dict = dict() get_bfs_alt(root, 0, level_dict) final_order = list() for i in range(len(level_dict)): final_order.extend(reversed(level_dict[i]) if i % 2 else level_dict[i]) return final_order # Tests n1 = Node(1) n2 = Node(2) n3 = Node(3) n4 = Node(4) n5 = Node(5) n6 = Node(6) n7 = Node(7) n2.ln = n4 n2.rn = n5 n3.ln = n6 n3.rn = n7 n1.ln = n2 n1.rn = n3 assert get_boustrophedon(n1) == [1, 3, 2, 4, 5, 6, 7] ``` ### API Architecture — Design Best Practices for REST APIs origin: [API Architecture — Design Best Practices for REST APIs](https://abdulrwahab.medium.com/api-architecture-best-practices-for-designing-rest-apis-bf907025f5f) #### 1. Learn the basics of HTTP An endpoint can be interpreted as an action performed on a resource. Example: POST: /books/ may mean "Create a new book". At a high-level, verbs map to CRUD operations: GET means Read, POST means Create, PUT and PATCH mean Update, and DELETE means Delete A response’s status is specified by its status code: 1xx for information, 2xx for success, 3xx for redirection, 4xx for client errors and 5xx for server errors #### 2. Do not return plain text You should still specify the `Content-Type` header. It must be set to the value `application/json`. #### 3. Do not use verbs in URIs ```sh GET: /books/:slug/bookCover/ # Don’t do this POST: /books/createNewBook/ # Do this POST: /books/ ``` #### 4. Use plural nouns for resources To prevent this kind of ambiguity, let’s be consistent (????Software career advice!) and use plural everywhere: ```sh GET: /books/2/ POST: /books/ ``` #### You should use HTTP status codes consistently ```sh GET: 200 OK PUT: 200 OK POST: 201 Created PATCH: 200 OK DELETE: 204 No Content ``` #### Do not nest resources ```sh # no GET: /authors/Cagan/books/ # yes GET: /books?authorName=Cagan ``` #### Handle trailing slashes gracefully ```sh POST: /buckets/ POST: /buckets ``` #### Make use of the querystring for filtering and pagination ```sh GET: /books?published=true&page=2&page_size=10 ``` #### Know the difference between 401 Unauthorized and 403 Forbidden - Has the consumer **not provided** authentication credentials? Was their SSO **Token invalid/timed out**? ???? 401 Unauthorized. Was the consumer correctly authenticated, but they **don’t have** the required permissions/proper clearance to access the resource? ???? 403 Forbidden. #### Make good use of HTTP 202 Accepted > I, the server, have understood your request. I have not created the resource (yet), but that is fine. > There are two main scenarios which I find 202 Accepted to be especially suitable: - If the resource will be created as a result of **future processing** — example: After a job/process has finished. - If the resource already existed in some way, but this should not be interpreted as an error. ### Misc - [.plan](https://news.ycombinator.com/item?id=29248368) - Finger Service: Port 79. The Finger protocol is based on Request for Comments document RFC 742 as an interface to the name and finger programs that provide status reports on a particular computer system or a particular person at network sites. The finger program was written in 1971 by Les Earnest who created the program to solve the need of users who wanted information on other users of the network. Information on who is logged-in was useful to check the availability of a person to meet. This was probably the earliest form of presence information for remote network users.