A Beginner’s Guide to Anonymous Types in C#

A Beginner’s Guide to Anonymous Types in C#

Anonymous Types C#
Anonymous Types C#

What are Anonymous Types in C#

Anonymous types are a mighty instrument in object-oriented programming disciplines. In strongly typed programming languages like C#, we need to always define the type of a variable before we can create new ones. Sometimes we have to create a new instance of an object with an unknown type and read-only attributes, which can be done only with explicitly undefined types.
By clearly describing small things, they can encapsulate attributes into an object without defining a type. And every single object can hold any combination of attributes, regardless of their data type, as long as each attribute is clearly defined and described.
They are perfect for the execution of SQL-like LINQ because they return an unspecified type to define the new object on the fly. It can help you streamline your C# and .NET code while also providing developers with a powerful tool for creating unidentified anonymous objects with a predefined structure.

How to Use Anonymous Types

Anonymous typing simplifies development and produces more readable and clean code. In combination with generics, you can create strongly typed collections, which can be useful with LINQ queries, passing attributes, or creating models in ASP.NET MVC.
Anonymous typing doesn’t work with inheritance or interface implementation. If you need a more complex type that requires functions or fields, your best choice is to define a class.

C# Anonymous Types Example

We made an array called “hackers” that has two objects in it with the values “Type” and “Exp“, a list called uniqueHackers, and a hash set called seenTypes.

The code iterates through the hackers array, and for each unique type, finds the maximum experience among all hackers. Finally, it creates a new object with a unique type and maximum experience and adds it to the uniqueHackers list.

This code will find the hacker(s) with the highest experience for each type of hacker. Note that it is a list of anonymous types, so you won’t be able to access the properties directly by name. Instead, you can use reflection or dynamic typing to access the attributes.

var hackers = new[] {
  new { Type = "Anonymous", Exp = 3 },
  new { Type = "Anonymous", Exp = 5 }
};
var uniqueHackers = new List<object>();
var seenTypes = new HashSet<string>();
foreach (var person in hackers) {
  if (!seenTypes.Contains(person.Type)) {
    seenTypes.Add(person.Type);
    var maxExp = person.Exp;
    foreach (var otherPerson in hackers) {
      if (person.Type == otherPerson.Type &&
otherPerson.Exp > maxExp) {
        maxExp = otherPerson.Exp;
      }
    }
    uniqueHackers.Add(new { Type = person.Type,
Exp = maxExp });
  }
}

Nested Anonymous Type in C#

Anonymous types can’t be used outside of the scope where they are defined, so they may not be suitable for more complex scenarios or for sharing data across multiple methods or classes.

This code is more concise and easier to read, especially when dealing with simple data structures. Here’s a code example of how you could create a nested anonymous type from the people array in the original code. It’s important to note that code readability can suffer if there are too many nested levels. In such cases, it may be preferable to utilize named types or nested classes instead.

var hackers = new[] {
  new {
    Type = "Anonymous",
    Exp = 3,
    Address = new {
      Street = "123 Main St",
      City = "Anytown",
      State = "CA",
      ZipCode = "12345"
    }
  },
  new {
    Type = "Anonymous",
    Exp = 5,
    Address = new {
      Street = "456 Elm St",
      City = "Sometown",
      State = "CA",
      ZipCode = "67890"
    }
  }
};

In this code example, the people array contains two objects, each with Type, Exp, and Address, which itself is an anonymous object with Street, City, State, and ZipCode properties. When dealing with complex data structures, we can utilize dot notation to access the nested properties like this:

Console.WriteLine(hackers[0].Type); 
// Output: Anonymous
Console.WriteLine(hackers[0].Address.Street); 
// Output: 123 Main St
Console.WriteLine(hackers[1].Address.City); 
// Output: Sometown

Anonymous Types in LINQ

LINQ can significantly simplify the code and enhance its readability when you work with complex data structures. To create an anonymous array using a LINQ query, modify the code as follows:

This snippet creates a new anonymousArray with Type and Exp properties. This code uses LINQ to sort by maximum experience, then creates an array with unique hackers, similar to the original code. There we have concise and readable code while still achieving the desired functionality.

Note that the order of the elements in uniqueHackers is not guaranteed, so we set the properties of each element in anonymousArray explicitly to ensure they match the original hackers array.

var hackers = new[] {
  new { Type = "Anonymous", Exp = 3 },
  new { Type = "Anonymous", Exp = 5 }
};
var uniqueHackers = hackers
  .GroupBy(h => h.Type)
  .Select(g => new { Type = g.Key, Exp =
g.Max(h => h.Exp) })
  .ToArray();
var anonymousArray = new[] {
  new { Type = uniqueHackers[0].Type, Exp =
uniqueHackers[0].Exp },
  new { Type = uniqueHackers[1].Type, Exp =
uniqueHackers[1].Exp }
};

Infrastructure As Code Tools Role│Best IaC Tools

Infrastructure As Code Tools Role│Best IaC Tools

Infrastrucrure As a Code Tools

Why Infrastructure As A Code Tools Used In Cloud Platforms?

IaC is a kind of methods used to control and describe centers of data processing with data sets for configuration rather than using manual methods of editing configurations on servers or interrelationships of infrastructures. Normally, the declarative method or imperative algorithm is used in writing code for operating with infrastructures.

Infrastructure as code (IaC) is a common set of tools used in cloud computing. The core principle of the IaC is to describe an infrastructure with a code in combination with an ordinary software development procedure. It is the main practice of developers and a component of a continuous software supply. IaC allows DevOps to work as a team promptly, reliably, and on large scales. They can use a single set of methods and tools to develop programs and servicing infrastructure.

From Hardware to Cloudformation tools

Many people probably no longer remember the iron age when we had to buy our own servers and computers. At that time no one had any idea what tools for cloud formation were. Now it already seems crazy when the hardware buying cycle can limit the infrastructure growth. A new server used to be delivered and installed for weeks! The software was available to developers many days after the hardware was installed.

The first cloud computing methods appeared only in the middle of the 2000s. This made it possible to run new instances of virtual machines quickly and brought businesses and developers not only benefits but also problems. First and foremost they had to maintain an increasing number of servers. However, these were still far from IaC tools.

Following that, only some large computers began to be replaced by smaller ones and the area of the infrastructure of an average engineering center began growing and became more cyclical. Ops had to support more and more things. In order to cope with the peak load, it was necessary to make up or down scaling at different times of the day.

To increase efficiency, many pickets had to be created in the morning to achieve the maximum power and many also at night to reduce that power. The whole process had to be managed manually, which became a challenge over time.

All abovementioned was the reason for the creation and introduction of the infrastructure as code tools. This allowed the systematization of the listed above task maximally. IaC solution made the management of the data processing centers and servers very sufficiently with the help of data readable by computers. They became an alternative to physical equipment and tool configuration under human supervision.

Amazon Web Cloud Formation Service (AWS) was the first tool that emerged in 2009. It became one of the best tools for DevOps allowing engineers to create versions of infrastructures as quickly as a normal code can make it as well. And that allows tracing the resulting versions of infrastructures in order, to make environments enough consistent.

Well-known Infrastructure As Code Tools

The TOP IaC tools that become famous recently among developers are:

  • Terraform IaC
  • Amazon Web Service Cloudformation tools (AWS)
  • Azure Resource Manager
  • Ansible
  • Chef
  • Puppet
  • Pulumi
  • Saltstack
  • Google Cloud Deployment Manager
  • Vagrant
  • Crossplane

Now, we would like to compare all aforementioned infrastructure as code tools to understand what similarities or differences they have concerning the application area, writing method, or languages.

Tool

Terraform

AWS CloudFormation

Azure Resource Manager

Google Cloud Deployment Manager

Pulumi

Ansible

Chef

Puppet

Crossplane

Vegrant

Saltstack

Method

Push

n/d

n/d

n/d

Push

n/d

Pull

Pull

n/d

n/d

Push/Pull

Approach

Declarative

Declarative

Declarative

Declarative

Declarative

n/d

Declarative and imperative

Declarative

Declarative

Declarative

Declarative and imperative

Language

HashiCorp Configuration

YAML or JSON

Azure

YAML or Python

Typescript, Python, or Go

YAML

Ruby

Ruby

YAML

Ruby, PHP, C#, Python, Java, JavaScript

Python

Applied for

Web and cloud formation services

Amazon Web Services

Access Control based on Role

Google Cloud resources and platforms

Azure Cloud services, WS, GCP

Users of modules and plugins

Cloud providers and web services

Cloud platforms and web services

Almost all cloud providers present on the market, architecture and cloud field

Engineers preferring few virtual PCs to big cloud-based infrastructures

Universal tool, fits any platform

Main Infrastructure As Code Tools Tasks

At the present time, it is hard to imagine the work of major providers and services without a cloud automation tool application. A wide range of IaCs is dedicated to helping IT engineers to solve such challenges as:

  • Deployment
  • Instrumentation
  • Configuration
  • Provisioning

Earlier IT specialists set, configured, and updated software for cloud servers manually. Team participants stored and configured data also with the same method. It took much time and required the attraction of additional developers and influenced significantly the increase in expenses.

IaC infrastructure as code became a solution for professionals in addressing such problems as additional expenses for salary payment and solving problems with the scalability.

It is worth being aware that some IaC tools are already set inside the settings of the infrastructure and other kinds of tools manage applications and infrastructure in the environment.

Below, we would like to give a few words about AWS infrastructure as code and its advantages.

AWS Infrastructure As Code Advantages

The IaC is aimed at the provision and management of cloud resources using a template read by people, which can be consumed by machines in an easy way. AWS Cloud formation is considered a reliable solution to the DevOps cloud services, which uses the IaC for Amazon Web Services.

AWS type of cloud formation enables creating a personal account of a user on Amazon Web Services using the description requested by a user. Then, this description is realized upon request. A typical infrastructure as code example includes a fragment of the template, which describes the creation of resources for the Amazon Elastic Computed Web Services using YAML.

Therefore, when we create the code, we indicate the AWS, then ECS and Service gradually as a Type, then put the “Discovery of the service” as the Dependence, also indicate in the properties the “App” as a name, “Production” as the cluster, 200 maximal percent and 75 minimal percent in the deployment configuration and set 5 as the number of counts.

AWS cloud formation tools then take the template and after that becomes responsible for the creation, updating, and removing resources on a user’s Amazon Web Service account depending on the content of this template. If a user wants to add a new resource to his file, the Cloudautomation tool builds this resource in his account. In case this user wishes to update his recourse, the tool can update or replace all current existing resources. If a user wants to delete this resource from his template, it will be vanished or be removed from his account.

Tools IaC provides users many pros:

They are visible:

An IaC template plays a big role as a precise reference on what kinds of resources you have on your account and their indicators. To check settings there is no need to follow the web panel.

They are scalable:

You can write the infrastructure as a code one time and then use it multiple times. It means that you can use just a good quality template as the basis for different services in various areas of the world, which significantly simplifies horizontal scaling.

They are stable:

If a wrong parameter or a wrong resource has been removed from the web panel, you can break everything. IaC tools solve this problem, especially in combination with Git versions for control.

They have transaction ability:

Cloudformation tools can not only create resources in your AWS account, but they also wait until their stabilization during the starting process. IaCs check for a successful initialization and in case of any failure, they can roll carefully the infrastructure back to the previously known good condition.

They are secure:

It can be seen that the provides of IaC again you with a single template to deploy your architecture. As soon as your protected architecture has been created, you can use it many times and you will know that each deployed version can have the same settings.

Conclusions

IaCs are very popular instruments of the new generation introduced at the beginning of the new century to make the process of cloud service formation, deployment, and adjusting of the infrastructure easier using just a code. There is no need to make manual settings, which significantly simplified the tasks of developers and solve a problem with scalability as well. Terraform and its closest analog Pulumi is considered the most common tools used for cloud formation.

FAQs

t

What problems do the infrastructure as code tools solve?

IaC tools are developed to fight such inconveniences as manual configuration of software for cloud and services. Engineers who didn’t have IaC were maintaining the settings of each environment of deployment separately. With time, each environment itself becomes a kind of unique configuration. Professionals call it a “snowflake”. Therefore, they cannot be reproduced automatically.

When environments do not fit each other, it causes problems with deployment. Administration and support of the infrastructure are always associated with manual adjusting leading to some errors, which are difficult to track. IaC tools enable avoiding a configuration process manually and make the environments consistent ensuring the desirable conditions for them with a qualitative code.

Why Terraform is always number one among the IaC tools?

Terraform is considered the best tool for DevOps and the most demanded in the market. It is an open-source IaC solution, which is very flexible and can support all the most promising and safe cloud services, such as Azure, GCP, or AWS.

It can also maintain many various cloud providers and manage them within a single workflow as it may destroy resources while sources are saved.

Terraform is considered a very cost-saving infrastructure as a code instrument as it is open-source by its nature and possesses a great range of quality tools and scripts.

What is the best Terraform alternative tool?

There are many tools IaC that are similar to Terraform in their approaches, usage, and description methods, which are commonly used in the Cloudformation platforms. However, it is worth highlighting the Pulumi IaC tool. Many specialists state that it has the same ability to create, manage and deploy infrastructure on any cloud. It is free and open-source like Terraform.

Binary Search Trees in Python – Grasp Information by KoderShop

Binary Search Trees in Python – Grasp Information by KoderShop

Binary Search Tree in Python

Binary Search Tree in Python (BST)

In this review, you will grasp more information about Binary search trees (BST). There will also be instances of BST in Python. Before starting to learn it, you need to familiarize yourself with what a Binary search tree is.

Python binary search tree uses a data structure that lets us keep values in a sorted list. Here each node is variable and this variable is bigger than its left child nodes. It is called binary sort in python.

There exists two reasons why this tree structure Python is called a Binary search tree. Firstly, each tree node has a max amount of child nodes of two (so that is why it is called a binary tree). Secondly, in O(log(n)) time search binary tree Python can be used to find a number (so that is why it is called a search tree).

The qualities that Binary search tree in Python has, and which make them different from regular binary trees:

  • Nodes which count as lower than the root node can be found in a node’s left subtree.
  • Nodes which count as bigger than the root node can be found in the right subtree of a node.
  • The both subtrees must be Binary search trees and possess the aforementioned characteristics.
  • There cannot be any duplicate nodes in binary search trees.

A tree has a right subtree with one value smaller than the root is shown to demonstrate that it is not a valid binary search tree program in Python

Binary Search Tree in Python example 1

The binary tree above isn’t a valid  Python binary search tree because the node “10” right subtree contains a value “9” that is smaller than it. The second property of BST Python is violated. But if we change the value “9” to “11”, it will be a Binary Python search tree. So let’s explain binary search tree with example:

Binary Search Tree in Python example 2

Now, what can we do with a binary search python program? So actually binary tree search Python can be used for storing something like data. The plus will be that it will be organized so you can without a doubt insert something, delete, and update. And also these operations will be as fast as lightning. As we said before BST can provide binary tree search complexity that is called Big-O of O(log(n)) when you are searching, updating or deleting data. Actually linear O(n) is slower than log(n) and it needs some time to find elements. And fact says that a lot of productions use binary trees in their databases like MySQL or PostgreSQL to speed them up when they use CRUD operations.

There are basic operations that you can perform on a binary search tree. Here is the binary search tree implementation. Below we will show basic operations that you can use with a binary search tree.

 

Let’s create a binary tree python. Tree node class python code can be used as a pointer so you can point to a root node that will connect to the child nodes. Here is the binary tree program in python:

class ExampleNode:
    def __init__(self, value=None):
        self.left_child = None
        self.right_child = None
        self.value = value

Here we will have a value that can function as a key. Also in the line of tree in python code:’value=None’ we can see that if a value will not be created, it will count as None. And in the next two lines, we create two child nodes that equal ‘None’.

Linear search in Python Binary search tree

Binary search algorithm in python depends on the quality of the Binary search treе that all of the left subtrees have values below the root node and all of the right subtrees have values above the root node.

Searching in Python for a value in a binary tree involves comparing the incoming value with the nodes. If this value is below the root node, it means that the value is not in the right subtree, so the search will take place in the left subtree accordingly if this value is above the root node, it means that the search will take place in the right subtree.

So now, let’s try to show steps on how it works. We are finding the number ‘11’:

Binary Search Tree in Python  example 3

Here our search method in Python has not found the number eleven, so it transfers to the right subtree to find it:

Binary Search Tree in Python example 4

Our search program in python has not found the number eleven here, so it transfers to the right node again because ‘10’ is a higher number than eleven:

Binary Search Tree in Python example 5

The search program in python has not found again the number ‘11’, and the number ‘12’ is higher than ‘11’ so it transfers to the left subtree:

Binary Search Tree in Python example 6

Finally, the number ‘11’ was found. Well done, binary tree search!

When the binary tree in Python finds our value, it returns. The returned value will spread in every step, so that means that if there will not be, for example, ‘12’, it will find it anyway. In situations when a binary tree can not find the value you need, it returns NULL. Here are the binary search algorithm steps:

Binary Search Tree in Python example 7

Let’s write a program for binary search in a data structure.

class ExampleNode:
    def __init__(self, value=None):
        self.left_child = None
        self.right_child = None
        self.value = value

def search_operation(self, value):
    if value == self.value:
        return True

    if value < self.value:
        if self.left_child == None:
            return False
        return self.left_child.exists(value)

    if self.right_child == None:
        return False
    return self.right_child.exists(value)

So here we see the easy search code in python that returns the boolean value True or False. Binary search python code tree depends on whether the value that we want to find exists or not.

Insert operation in Python Binary search tree

When we want to insert something, for example, a value, we use the same technique as searching because we obey the only rule that in the right subtree there must be larger values and in the left subtree there must be lower values than in our root node.

So the insert technique differs from searching in putting the new node. It looks like that we go through each subtree depending on the value and we put the new node when the left or right subtree is NULL.

Example of binary tree code in python:

If node_root == NULL 
    return createNode(data)
if (data < node_root ->data)
    node_root ->left = insert(node_root ->left, data);
else if (data > node_root ->data)
    node_root ->right = insert(node_root ->right, data); 
return node_root ;

So now, let’s try to show steps on how it works. We are going to add the number ‘11’:

Binary Search Tree in Python example 8

Here we can see that ‘11’ is higher than our root ‘7’ so the Python binary search program transfers to the right subtree:

Binary Search Tree in Python example 9

Now again ‘10’ is higher than ‘11’ so we transfer to the right:

Binary Search Tree in Python example 10

Here is the last transfer, because the number ‘11’ is lower than ‘12’ so which means we’re gonna transfer to the left subtree. And we see that the left subtree is NULL so we add ‘11’ here. Hooray!

Binary Search Tree in Python example 11

So we put the node with the number ‘11’, but we did not exit the operation, because we needed to return the value. So here the return node comes in hand. The process of returning a node works when we have NULL and create the new node that is returned and attached to the parent node. If we have not found the position for a new node, we without change come back to the root in reverse order.

That means that we move in reverse order in the tree without changing other connections.

Binary Search Tree in Python example 12

Here we see how in each step we come back to the root without changing any value.

Also, let`s try to create a Python binary search code for this operation:

class ExampleNode:
    def __init__(self, value=None):
        self.left_child = None
        self.right_child = None
        self.value = value

def insert_operation(self, value):
    if not self.value:
        self.value = value
        return

    if self.value == value:
        return

    if value < self.value:
        if self.left_child:
            self.left_child.insert(value)
            return
        self.left_child = ExampleNode(value)
        return

    if self.right_child:
        self.right_child.insert(value)
        return
    self.right_child = ExampleNode(value)

Here we see that we created a python program for binary search where the given value sets and returns if the node does not own a value. But if our node contains the value, it returns it. Also, we used the rule that if the value is lower than the value that is in our node and we have a left child, we recursively call insert on this child. In the opposite case, if we do not have the left child, we just create it with the value that was given. And all the same, is for the right child, but only if our value is higher.

Delete operation in Python Binary search tree

The operation of deleting the node has three variations:

First BST variation:

Binary search in Python program deletes the node that was located in the end of the tree and does not change any connections. For example, we want to delete the number ‘11’:

Binary Search Tree in Python example 13

Here python binary search algorithm detected the value and deleted it:

Binary Search Tree in Python example 14

Second BST variation:

When we delete the node that has a child node. For example, we need to delete the number ‘12’:

Binary Search Tree in Python example 15

Here we detected the number ‘12’. Next, we copy the value of its child. Our child is number ‘14’. So we copy this value:

Binary Search Tree in Python example 16

We have already copied the child ‘14’.Then we do the same step as in ‘First variation’, we delete the last node:

Binary Search Tree in Python example 17

Third BST variation:

When we have more than one child below the node we are searching for deleting. For instance, we need to delete the number ‘10’ from the tree:

Binary Search Tree in Python example 18

Here we detected the value. Now we must find the successor of the number ‘10’ in the tree. It is ‘11’, so we copy the value:

Binary Search Tree in Python example 19

Then we finally delete the node of successor ‘11’:

Binary Search Tree in Python example 20

Let’s try to make the program for binary search in python with delete operation:

class ExampleNode:
    def __init__(self, value=None):
        self.left_child = None
        self.right_child = None
        self.value = value

def delete_operation(self, value):
    if self == None:
        return self
    if value < self.value:
        self.left_child = self.left_child.delete(value)
        return self
    if value > self.value:
        self.right_child = self.right_child.delete(value)
        return self
    if self.right_child == None:
        return self.left_child
    if self.left_child == None:
        return self.right_child
    minimum_larger = self.right
    while minimum_larger.left_child:
        minimum_larger = minimum_larger.left_child
    self.value = minimum_larger.value
    self.right_child = 
    self.right_child.delete(minimum_larger.value)
    return selfdef delete(self, value):
    if self == None:
        return self
    if value < self.value:
        if self.left_child:
            self.left_child = self.left_child.delete(value)
        return self
    if value > self.value:
        if self.right_child:
            self.right_child = self.right_child.delete(value)
        return self
    if self.right_child == None:
        return self.left_child
    if self.left_child == None:
        return self.right_child
    minimum_larger = self.right_child
    while min_larger_node.left:
    minimum_larger = minimum_larger.left
    self.value = minimum_larger.value
    self.right_child = 
    self.right_child.delete(minimum_larger.value)
    return selfdef delete(self, value):
    if self == None:
        return self
    if value < self.value:
        self.left_child = self.left_child.delete(value)
    return self
    if value > self.value:
        self.right_child = self.right_child.delete(value)
    return self
    if self.right_child == None:
    return self.left_child
    if self.left_child == None:
    return self.right_child
    minimum_larger = self.right_child
    while minimum_larger.left:
    minimum_larger = min_larger_node.left
        self.value = minimum_larger.value
    self.right_child = 
    self.right_child.delete(minimum_larger.value)
    return self

So here we see this huge tree in Python data structure. But do not worry, it is simple. Actually, this operation works recursively, but it returns the new shape of the node that was given after doing the delete. And it helps in giving access to the parent node whose child node was deleted so we can properly set where the data must be in the left node and where it must be in the right node.

Getting minimum and maximum

with Python Binary search tree

class ExampleNode:
    def __init__(self, value=None):
        self.left_child = None
        self.right_child = None
        self.value = value

def get_minimum(self):
        exact_value = self
        while exact_value.left is not None:
            exact_value = exact_value.left
        return exact_value.value

def get_maximum(self):
    exact_value = self
    while exact_value.right is not None:
        exact_value = exact_value.right
    return exact_value.value

Here we see a very straightforward tree class in Python that can be helpful. They transfer the edges of the data structure tree Python so we can find the largest and the smallest values in our storage.

Why would you need binary trees?

Let’s define a python tree node class. Binary search trees Python can provide very fast O(log(n)) operations that were mentioned before. They are useful for binary sorting in Python. It is very simple to understand and very useful. A simple node class in python without any operations needs only a few lines of code to get to work.

What about the cons? Binary search trees in data structure python are slow for force-brute search. If you want to have iterations through each node, you must better use arrays. Also, BST requires more memory than arrays in implementation.

Actually, there are a lot of appliances where the data tree python will be useful. So the easiest solution to the problem of storing indexes and keys in the database will be BST.

Let’s imagine the example when you need to create a main key column in SQL databases. So here you can without a doubt use a binary python class tree where keys are values in the column and you can point to the rows with nodes. In this situation your SQL base will be easy to search by using keys.

For example, you need to create a game where there must be a list of records of users. It is easy to find the nickname of the user by using binary tree search. And there are more apps where class tree python will be useful. Other simple uses for binary trees you can find in Google.

 

But what should I use? Binary search in python using list or the binary trees? For this question there are a lot of different answers. They are both positive and negative. Firstly, python node tree use the same pointers to track where the node is as linked lists. But node class python is more efficient and faster while you are searching.

Will Setter and Getter be the Best Accessors? Let’s See the Difference by KoderShop

Will Setter and Getter be the Best Accessors? Let’s See the Difference by KoderShop

Getter setter Python
Getter setter Python

What is Getter and Setter in Python?

After using C++ or other languages you can know how to define getters and setters. But if you start learning the first language Python, you can see that they are not so popular. Often people use them for attributes for classes. They help in creating access for private attributes while preserving encapsulation. But in Python you usually use them to uncover attributes partially in public API and use things when you need attributes with useful actions.

Although it is in Pythonic style to use properties, they can anyway have disadvantages. That’s why people start using getters and setters Python more than properties. And also you must know some OOP or in long: object-oriented programming.

After specifying the class in object-oriented programming, usually you use class attributes and instances. And the attributes that you have created are variables that you can use using instances or the class or both.

Firstly, let’s try to create a class in Python.

How to Create Class

If you need to create the class first you need to use the class name and variables. Here is an example:

class Example:
    first = "Hello"
    second = "Kodershop"

Here we have created the class with the name Example. Let’s create objects from this class:

class Example:
    first = "Hello"
    second = "Kodershop"
Example1 = Example() 
print(Example1.first, Example1.second, "!")
#Output:
#Hello Kodershop !

So here the object was created which is called Example1 and it is from the Example class.

That all means that when we printed Example1.first, we had got the value that was stored in a variable in the class that we had created. This calling and these variables are our attributes of the class.

Python Class Attributes

So the basic getter definition of attributes in class is that variables in class can be inherited by objects in the class. The next examples will show how it looks in code, but the only thing we must say is that those attributes are written outside the function __init__().

Let’s see the example:

class Example:
    office = "Dear Kodershop!"
        def __init__(self, name, position):
        self.name = name
        self.position = position
Example1 = Example("Steve", "CEO")
Example2 = Example("Alex", "Co-founder")
print(Example1.name, "is the best worker, but", Example2.name, "is the best blog post employee!")
#Output:
#Steve is the best worker, but Alex is the best blog post employee!

So here we created the variable called ”office” in the class called Example. Then we used ”init” to create two more variables that are “name” and “position”. “Self” parameter inside init helped us to initialize them.

Python Setter Getter Strategies

So what are a getter and setter? Subsequently, the nation of the objects is held in attributes. In case you want to get admission to this kingdom, you need to have an entry to these attributes. So to get entry to those attributes you can use techniques or access them without delay.

After revealing them to different users, these attributes become part of the elegance’s API. So public attributes imply that other customers can have entry to the attributes in their snippets of codes.

Whilst you are in this example, languages like C++ want to use some techniques to address attributes in lessons. And as you can determine, they may be setters and getters.

Strategies of getter and setter Python have become properly appreciated in programming languages. Human beings use them for item-oriented programming, so surely there are a lot of human beings who’ve already heard about them.

So what are getters setters? If we need to talk about the usage of easy definitions, we are able to say that getter is the method that allows you to have an opportunity to have access to the values in a characteristic. And setter is the method that helps you to change or insert the cost inside the attribute.

 

Our everyday techniques submit that attrs which are public are operated when you have decided that nobody from builders will ever contact them. While you need to change the inner implementation of the attribute, you will use setter getter Python methods. To enforce the setter and getter it’s required to make the attributes non-public and write each characteristic with setter and getter. For example, say that you want to jot down a Room magnificence with width, length, and height attributes. Permit’s use getters and setters:

For instance, say that you need to jot down a python class getter setter with width, length, and height attributes. Let’s use getters and setters:

class Room:
    def __init__(self, width, length, height):
        self._width = width
        self._length = length
        self._height = height

    def get_width(self):
        return self._width

    def set_width(self, value):
        self._width = value

    def get_length(self):
        return self._length

    def set_length(self, value):
        self._length = value

    def get_height(self):
        return self._height

    def set_height(self, value):
        self._height = value

Here we can see that the constructor of our class uses three arguments that are width, height, and length. And we saved them in “._width”, “._length”, “._height” non-public attributes.

Often, you can use getter Python methods for returning the focused value of an attribute. And setter methods you use to make a new value and change it in this attribute.

Also, when you are used to programming C++ you can see that Python does not have private, protected, or public modifiers. Python has only public or non-public.

When you want to mark the attribute as non-public, you can use Python in-built syntax that is written before the name. It looks like the underscore “_”. This is only syntax, so it does not ruin all your plans of using dot notation like “object._attribute”. Dot notation is used often in “self.name” or anything else.

Also to use your code and make it work you can use “import”:

class Room:
    def __init__(self, width, length, height):
        self._width = width
        self._length = length
        self._height = height

    def get_width(self):
        return self._width

    def set_width(self, value):
        self._width = value

    def get_length(self):
        return self._length

    def set_length(self, value):
        self._length = value

    def get_height(self):
        return self._height

    def set_height(self, value):
        self._height = value

room = Room(15, 16, 13)
print("Width:", room.get_width())
room.set_width(25)
print("New width:", room.get_width())
print("Length:", room.get_length())
#Output:
#Width: 15
#New width: 25
#Length: 16

Let’s explain what we have done here. As we know the Pythonic way to add behavior for attributes is to make them a property. Properties percent together strategies for getting, setting, deleting, and documenting the underlying data. In short, properties we can call as attributes that have additional behavior.

Actually, it’s not a problem to use properties in the same way as stock attributes. Whilst you get entry to a property, its attached getter method is robotically called. And whilst you mutate the property, its setter technique is called.

The room gives us the opportunity to make instances so we can make changes to the associated height, width, and length.

Features of Setter and Getter

Using a setter and getter only for accessing or changing the values is not the only way. When you want to save all values in uppercase you can also use them. Well, you may use it by attribute ”.text” but you can’t. So if you want to use it, it seems that you have come from Java and C++ because they do not support constructs that are like properties. So that’s the issue why you can not use your attributes here as public. You should use setter and getter and provide implementation without public.

Python properties have plenty of capacity use cases. For instance, we can make properties to form read-write, read-only, and write-only attributes. Properties will let you delete and record the underlying attributes and also more interesting is that you can make them act like controlled attributes with attached behavior without converting the way you figure with them.

Because of Python possibilities when you use properties, people generally tend to use them. So if you need to add some new processing with attributes you can use them. But when you want to change all your attributes, you will waste a lot of time. And even it can overload your code and make it less efficient.

Descriptors in Python

Now after we get to know the base of topics about getter setter Python, also about properties that are written in a Pythonic way and also dealing with problems with how to add more functionality, we can learn other tools and techniques that we may use when we want to change getter and setter in Python on other methods.

So a descriptor is a feature in Python that helps you in creating attributes with behaviors. If you want to create a descriptor, you must use the specified protocol. In other words, it is a syntax that helps you. They are “.__get__()” and “.__set__()” methods.

Factual descriptors are very similar to properties in Python. Or in other words, Python class property setter is a type of descriptor that is more powerful than an in-built property. To clarify a case of how to use descriptors to create attributes with useful behavior, let’s use the example before:

class Room:
    def __init__(self, width, length, height):
        self._width = width
        self._length = length
        self._height = height

    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, value):
        self._width = value

    @property
    def length(self):
        return self._length

    @length.setter
    def length(self, value):
        self._length = value

    @property
        def height(self):
        return self._height

    @height.setter
    def height(self, value):
        self._height = value

Here we have used “@property” and “@.setter” which allowed us to change the height, width, and length for each room. In general, in case you locate yourself disordering your instructions with comparable property definitions, you ought to not forget to use a descriptor instead.

Methods __setattr__() and __getattr__()

Except traditional getters Python and setters you can use .__setattr__() and .__getattr__() special methods that help you to manage the attributes. Let’s make a class named Position that will change the type of x and y into float:

class Position:
    def __init__(self, x_value, y_value):
        self.x_value = x_value
        self.y_value = y_value

    def __getattr__(self, firstname: str):
        return self.__dict__[f"_{firstname}"]

    def __setattr__(self, firstname, value):
        self.__dict__[f"_{firstname}"] = float(value)

Here we can see that __init__ takes our position coordinates “.__getattr__()” method returns the firstname that is the coordinate. To make this done we used “.__dict__”. Take note that Python use  “.__getattr__()” automatically when you try to access an attribute with dot notation. What about the “.__setattr__()” method is that adds or changes the attributes. For example we used it for operating with each positional coordinate and converting it into float type. And also as with “.__getattr__()”, “.__setattr__()” runs automatically when you use assignment operation.

class Position:
    def __init__(self, x_value, y_value):
        self.x_value = x_value
        self.y_value = y_value

    def __getattr__(self, firstname: str):
        return self.__dict__[f"_{firstname}"]

    def __setattr__(self, firstname, value):
        self.__dict__[f"_{firstname}"] = float(value)

position = Position(21, 42)
print("The toy located in:\nx =", position.x_value)
print("y =",position.y_value)

position.y_value = 84
print("new y =",position.y_value)
#Output:
#The toy located in:
#x = 21.0
#y = 42.0
#new y = 84.0

Here in our class we have to get or set accessors expected with our positions as regular attributes.

So here we used a very interesting example and showed how it works. But actually, you will not use similar. The tools that we have used help you to make validations and transformations with access to our attribute.

And in short, “.__getattr__()’’ and “.__setattr__()” are like an implementation that is like a Python getter and setter pattern. But actually, they work the same as regular methods getters and setters.

What Does Inheritance Look Like?

If you want to inherit some classes in Python you will meet up with one problem. For instance, you want to change the Python property method in a subclass. And if you try to Google it, you do not find any safe ways to do this. In short, it is hard to overturn the regular getter and wait that this property getter and setter will have the same functions as in the parent class. So that means that when you try to change the method in the inherited class you change the whole property including its other methods as a setter. Let’s see the example:

class Goods:
    def __init__(self, title):
        self._title = title

    @property
    def title(self):
        return self._title

    @title.setter
    def title(self, value):
        self._title = title

class Room(Goods):
    @property
    def title(self):
        return title

Here we can see that in class “Room” we changed the @property. This case shows us that we changed the whole .title property, including example setter too. Let’s add some functions:

class Goods:
    def __init__(self, title):
        self._title = title

    @property
    def title(self):
        return self._title

    @title.setter
    def title(self, value):
        self._title = value

class Room(Goods):
    @property
    def title(self):
        return super().title
banana = Room("banana")
print("I want", banana.title)

banana.title = "new banana"
print("No, I want", banana.title)
#Output:
#AttributeError: Object does not support property or method

Here we can see how Python can not find the setter of the inherited class. This is because we have changed it before and we are now trying to use a false setter, but he was not inherited. So, what is the solution to this situation?

Let’s use regular get set in Python methods:

class Goods:
    def __init__(self, title):
        self._title = title

    def get_title(self):
        return self._title

    def set_title(self, value):
        self._title = value

class Room(Goods):
    def get_title(self):
        return super().get_title()

Here we see that no issues were found. Python has an in-built independent get and set in Python methods. Room is a subclass of Goods and it overrides the getter. We can see that this line of code does not change the functionality of setter and successfully it was inherited from the parent class.

Let’s make an example with get set Python and functions:

class Goods:
    def __init__(self, title):
        self._title = title

    def get_title(self):
        return self._title

    def set_title(self, value):
        self._title = valueclass Room(Goods):

    def get_title(self):
        return super().get_title()

banana = Room("banana")
print("I want", banana.get_title())

banana.set_title("new banana")
print("No, I want", banana.get_title())
#Output:
#I want banana
#No, I want new banana

Now our class can work properly. The changed getter method in the inherited class is functional. And the setter method also works well. Well done!

What is Better? Set and Get in Python or Properties?

If you start coding, you know the answer. There are some situations where methods of setter and getter are preferred over properties, but also there are other situations where Pythonic properties play better.

Let’s try to distribute by points why the get and set in Python are dealing with better, we can do this. When we talk about transformations, the methods setter and getter run better on attribute Python accessors and mutation Python. Also, they use inheritance and this is very good. Getter and setter can raise Python exception attributes when they are accessing the attributes. And finally, their integrations are being facilitated in heterogeneous enhancement teams.

When we want to talk about properties in Python, the problem can be seen when you are making a huge amount of lines of code. In other words, take note that you should avoid making slow Python mutations with Python properties. When somebody repeatedly tries to make access to a given attribute, users can suffer from waiting because it can take a long time, and the efficiency of your code can suffer a lot. So when your plans are to use Pythonic properties to change values in attributes, be sure that your mutations are fast, because if you will not do that and use slow get set accessors, you will change your code to use a simple setter and getter.

Another situation is that getter and setter methods are more flexible than you would think. Let’s make an example with the name Goods and its expiration date attribute:

class Goods:
    def __init__(self, title, expiration_date):
        self.title = title
        self._expiration_date = expiration_date

    def get_expiration_date(self):
        return self._expiration_date

def set_expiration_date(self, value, force=False):
    if force:
        self._expiration_date = value
    else:
        raise AttributeError("Can't set expiration_date. Have you written it in numbers?")

Our date was a constant value and we made it read-only, so it means non-public. Also because of the fact that human error exists, so in life, you will face a lot of cases where somebody writes letters instead of numbers in the date section. Here we provided regular getter and setter methods for the “.expiration_date” attribute. Here our setter method has taken the “force” argument so that we can be ready for mistakes made by people. Also factually, traditional setters do not use more than one argument in code, so we can say that our code is wrong.

class Goods:
    def __init__(self, title, expiration_date):
        self.title = title
        self._expiration_date = expiration_date

    def get_expiration_date(self):
        return self._expiration_date

    def set_expiration_date(self, value, force=False):
        if force:
            self._expiration_date = value
        else:
            raise AttributeError("Can't set expiration_date. Have you written it in numbers?")

milk = Goods("A packet of milk", "2023-5-29")
print("Milk:", milk.title)
print("Milk expiration date:", milk.get_expiration_date())

milk.set_expiration_date("2023-6-29")
#Output:
#Traceback (most recent call last):
#AttributeError: Can't set expiration_date. Have you written it in numbers?

Here we have written the code without the “force” argument and got a message. Let’s make it work properly:

class Goods:
    def __init__(self, title, expiration_date):
        self.title = title
        self._expiration_date = expiration_date

    def get_expiration_date(self):
        return self._expiration_date

    def set_expiration_date(self, value, force=False):
        if force:
            self._expiration_date = value
        else:
            raise AttributeError("Can't set expiration_date. Have you written it in numbers?")

milk = Goods("A packet of milk", "2023-5-29")
print("Milk:", milk.title)
print("Milk expiration date:", milk.get_expiration_date())

milk.set_expiration_date("2023-6-29", force=True)
print("New milk expiration date:", milk.get_expiration_date())
#Output:
#Milk: A packet of milk
#Milk expiration date: 2023-5-29
#New milk expiration date: 2023-6-29

In the first example we tried to change the expiration date by using .set_expiration_date. But the problem was that we did not use force argument – we have not changed its setting to True. That is why we have got an AttributeError. So in the next example we replaced its setting and said to Python that we are sure that there are no mistakes. So it worked.

As we said before, the Python property setter getter does not accept more than one argument in the setter, because it accepts only that variable that you want to change or make.

 

Usually, you won’t accept a work message like “objects.attributes = value” to heighten an exception. Especially, you may accept messages that heighten exceptions in response to mistakes. Here regular Python getter setter methods were extra specific than properties.

Let`s look like on line: “phone.number = ‘360’”. Undoubtedly, it looks like something that will work in a solid way and will not raise an exception. It is an ordinary attribute. But if we use a setter like here: “phone.set_number(‘360’)”, we can see that it can heighten a message about a value error. “inserted phone number is not a phone number.”. In this case, the setter method is a better way to solve this. It simply expresses the code’s beneficial behavior.

Generally, keep away from raising exceptions from your Python properties. You can do that only if you want to use a property to offer attributes that will be only for reading. If you ever need to heighten messages on access or mutation, then you absolutely shouldn’t forget to use getter and setter methods in place of properties.

So in short, using a regular setter and getter can help in solving troubles when they make their code.

 

In the end, we can wrap up that we know better what is setter and getter methods. But they are not so popular because Python has in-built properties that allow you to mutate and get access to the attributes. But genuinely, as we have before in some situations they have drawbacks that you can fix only by changing properties in regular Python get and set methods.

Instructions for Setting Up HTTPS and SSL Using Azure

Instructions for Setting Up HTTPS and SSL Using Azure

HTTPS Azure

How to use HTTPS with Azure and install SSL

HTTPS (Hypertext Transfer Protocol Secure) is a secure version of the HTTP protocol used for transmitting data over the internet. It encrypts communication between a website and its visitors to protect sensitive data from being intercepted. In today’s internet landscape, it is becoming increasingly important for website owners to use HTTPS to secure their websites and protect their visitors’ data.

HTTPS connection with Azure

One way to implement HTTPS on a website is through Azure, a cloud computing platform and infrastructure created by Microsoft. Azure offers a range of tools and services that can be used to secure and manage a website, including options for implementing HTTPS.

There are several ways to enable HTTPS on a website hosted on Azure. One option is to use Azure App Service, which is a platform-as-a-service (PaaS) offering that allows developers to build and host web applications. With Azure App Service, website owners can enable HTTPS by simply turning on the “HTTPS Only” option in the App Service configuration.

Instructions for setting up HTTPS with Azure App Service

To enable HTTPS with Azure App Service, follow these steps:

  1. Navigate to the App Service page in the Azure portal.
  2. Select the app for which you want to enable HTTPS.
  3. In the left-hand menu, click on “SSL certificates.”
  4. Click on the “HTTPS Only” option.
  5. Click on the “Save” button to apply the changes.

Once HTTPS is enabled for an app, Azure App Service will automatically provision and bind a certificate to the app. This certificate will be valid for one year and will be renewed automatically by Azure App Service.

HTTPS with Azure CDN and SSL certificate

Another option for enabling HTTPS on a website hosted on Azure is to use Azure CDN (Content Delivery Network), which is a global network of edge nodes that helps to deliver content faster and more reliably to users. With Azure CDN, website owners can enable HTTPS by creating a custom domain and purchasing a SSL/TLS certificate. The certificate can then be configured to work with Azure CDN by following the steps in the Azure documentation.

Instructions for setting up HTTPS with Azure CDN

To enable HTTPS with Azure CDN, follow these steps:

  1. Navigate to the Azure CDN page in the Azure portal.
  2. Select the CDN profile for which you want to enable HTTPS.
  3. In the left-hand menu, click on “Custom domains.”
  4. Click on the “Add custom domain” button.
  5. Enter your custom domain name and select the desired protocol (HTTP or HTTPS).
  6. Click on the “Validate” button to verify that you own the domain.
  7. Once the domain is validated, click on the “Add” button to add the custom domain to your CDN profile.
  8. Click on the “Add binding” button to bind the custom domain to your CDN endpoint.
  9. In the “Add binding” window, select the custom domain and the desired protocol (HTTP or HTTPS).
  10. Click on the “Add” button to add the binding.

After the custom domain is added and bound to the CDN endpoint, website owners can purchase a SSL/TLS certificate and configure it to work with their custom domain. This can be done through Azure or through a third-party provider. Once the certificate is configured, website owners can enable HTTPS by turning on the “HTTPS Only” option in the CDN endpoint configuration.

In addition to these options, Azure also offers other tools and services that can be used to secure a website and enable HTTPS, such as Azure Traffic Manager and Azure Key Vault. These tools can be used to manage and secure traffic to a website.

Installing SSL and Azure

After the custom domain is added and bound to the CDN endpoint, website owners can purchase a SSL/TLS certificate and configure it to work with their custom domain. This can be done through Azure or through a third-party provider. Once the certificate is configured, website owners can enable HTTPS by turning on the “HTTPS Only” option in the CDN endpoint configuration.

In addition to these options, Azure also offers other tools and services that can be used to secure a website and enable HTTPS, such as Azure Traffic Manager and Azure Key Vault. These tools can be used to manage and secure traffic to a website.

Conclusion

This article will show you how to enable HTTPS in Azure web applications using Azure App Service. We also discussed some best practices and its up to you to choose which one should you use.