Friday 26 December 2014

Python built-in: setattr(), getattr()

setattr(object, name, value)


setattr() sets a named attribute on an object. The arguments are an object, a string and an arbitrary value.
setattr(x, 'foobar', 123) is equivalent to x.foobar = 123.

Example Usage:

Lets assume Peter's mother has to write a class for preparing tiffin box for her son Peter who does not want to eat very regularly. Everyday in a week she puts random sandwichs and fruits in the tiffin box and checks if peter has eaten that or not. Let help her write the class using setattr()

class TiffinBox(object):
    def __init__(self):
        setattr(self, random.choice(['bacon', 'egg', 'jam']),
             random.choice(range(1, 4)))
        setattr(self, random.choice(['bacon', 'egg', 'jam']), 
             random.choice(range(1, 4)))

Here we are setting a random food with a random number from 1 to 3. The number defines the amount of that food in Peter's tiffin box.
Now we also want Peter to drink something and check if he has eaten the food. Let's write some methods in this class to do those.

class TiffinBox(object):
    def __init__(self):
        setattr(self, random.choice(['apple', 'banana', 'oranges']), 

             random.choice(range(1, 4)))
        setattr(self, random.choice(['bacon', 'egg', 'jam']), 

             random.choice(range(1, 4)))

    def take_drink(self):
        drinks = random.choice(['coffee', 'tea'])
        setattr(self, 'drink', drinks)

    def eat_food(self):
        for food in self.__dict__:
            setattr(self, food, 0)
        setattr(self, 'eaten', True)


Peter can eat using eat_food method and if he eats that food we will add a new attribute to the object named eaten set it to Boolean True and make the all the food count 0 assuming Peter ate all the foods.
We can also add a weekday attribute here. Now the class looks like this.

# -*- coding: utf-8 -*-
import random
from datetime import datetime

class TiffinBox(object):
    def __init__(self):
        setattr(self, random.choice(['apple', 'banana', 'oranges']), random.choice(range(1, 4)))
        setattr(self, random.choice(['bacon', 'egg', 'jam']), random.choice(range(1, 4)))
        self.tiffin_day = self.get_weekday(datetime.now().weekday()) + '_tiffin'
    def __str__(self):
        return self.tiffin_day

    def take_drink(self):
        drinks = random.choice(['coffee', 'tea'])
        setattr(self, 'drink', drinks)

    def get_weekday(self, weekday):
        py_week = {
            0: 'monday', 1: 'tuesday', 2: 'wednesday', 3: 'thursday', 4: 'friday', 5: 'saturday',6: 'sunday' }
        return py_week.get(weekday)

    def eat_food(self):
        for food in self.__dict__:
            setattr(self, food, 0)
        setattr(self, 'eaten', True)

Now Peter's mother can prepare tiffin for him.

>>>tiffin =TiffinBox()
>>>tiffin.__dict__
>>>{'apple': 3, 'jam': 3, 'tiffin_day': 'friday_tiffin'}
>>>tiffin.eat_food() 
>>>tiffin.__dict__
>>>{'eaten': True, 'apple': 0, 'jam': 0, 'tiffin_day': 'friday_tiffin'}

Neat !!

getattr(object, name[, default]) -> value


getattr() is a python built-in that gets a named attribute from an object and return the value of that attribute.
The attribute name must be a string. getattr(x, 'y') is equivalent to x.y. default is an optional argument.
If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

>>>la = range(5)
>>>getattr(la, 'pop') 
<built-in method pop of list object at 0xb7470eac>
>>>la.pop
<built-in method pop of list object at 0xb7470eac>

so getattr(la, 'pop') is equivalent to la.pop. It can be used like a function also.

>>>getattr(la, 'pop')()
4
>>>getattr(la, 'abc')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'abc' 

A  list object has no attribute named 'abc'. So a AttributeError is raised here. But if we use the optional default argument, then the default value is returned.

>>> getattr(la, 'abc', 'no such attribute')
'no such attribute'

Example Usage:

Let's help Peter to find out what his mother has put in the box and in how many amount. He does not know if it's a apple or banana, bacon or jam! Time to use getattr()

mybox = TiffinBox()

for atr in mybox.__dict__:
    print atr, ': ', getattr(mybox, atr)


tiffin_day :  friday_tiffin
bacon :  2
oranges :  3


Hope Peter likes bacons and oranges!




Wednesday 24 December 2014

Python built-in: any(), all()


any(iterable) -> bool


any(iterable)  is a built-in function in python's  __builtin__ module. It returns True if bool(x) is True for any x in the iterable. If the iterable is empty, return False.
Now let's take a list.

>>>la = [True, False, False]
>>>any(ls)
>>>True

This returns True because at least one of the value in la was True. Let's take another list,

>>>lb = [False, False, False, False]
>>>any(lb)
>>>False 

So any() will return True if at least one of the value in the iterable is True else it will return False.

Example Usage:


>>>str = "Wikipedia is the seventh-most popular website \
...and constitutes the internet's largest and most popular \
...general reference work"
>>>keywords = ['Google', 'Wikipedia', 'Facebook', 'Microsoft']

We want to check if there is keyword from keywords list is present in the string str. With the use of any() function it can be done in a one-liner!

>>>any(keyword in str for keyword in keywords)
>>>True

That's awesome!! isn't it? But what sorcery is this? Breaking it down:

>>>[keyword in str for keyword in keywords]
>>>[False, True, False, False]

So it's like the earlier la, lb type list. It's returning True for the keyword 'Wikipedia'. Now what is happening in the list
compression is:

for keyword in keywords:
    if keyword in str:
        # append True in a_list
    return <a_list>

 

all(iterable) -> bool


This function takes an iterable as argument and returns True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True.

It will return if all the values in the iterable are True.

>>>all(la)
>>>False
>>>all(lb)
>>>False

>>>lc = [True]*3
>>>all(lc)
>>>True

 

Example Usage:


We are going to check if a list is a odd number list.

>>>all(map(lambda x:x%2==1, range(1, 10, 2)))
>>>True

Breaking it down:

>>> range(1, 10, 2)
>>>[1, 3, 5, 7, 9]

map() is a built-in which will return a list of result applying the lambda function to the item of the [1, 3, 5, 7, 9] list.

>>>map(lambda x:x%2==1, range(1, 10, 2))
>>>[True, True, True, True, True]
>>> all([True, True, True, True, True])
>>>True

Nice!!