# PYTHON QUESTIONS 2 – 2017

## Hamming distance

In information theory, the Hamming distance between two strings of equal length is the number of positions at which the corresponding symbols are different:

Here is the code for the Hamming distance:

```def hamming(s1,s2):
if len(s1) != len(s2):
raise ValueError("Not defined - unequal lenght sequences")
return sum(c1 != c2 for c1,c2 in zip(s1,s2))

if __name__ == '__main__':
print(hamming("karolin", "kathrin")) # 3
print(hamming("karolin", "kerstin")) # 3
print(hamming("1011101", "1001001")) # 2
print(hamming("2173896", "2233796")) # 3
```

## Floor operation on integers

Write a floor division function without using ‘/’ or ‘%’ operator. For example, f(5,2) = 5/2 = 2, f(-5,2) = -5/2 = -3.

```def floor(a,b):
count = 0
sign = 1
if a < 0: sign = -1
while True:
if b == 1: return a
# positive
if a >= 0:
a -= b
if a < 0: break
# negative
else:
a = -a - b
a = -a
if a > 0:
count += 1
break
count += 1
return count*sign

from random import randint
n = 20
while n > 0:
a, b = randint(-20,20), randint(1,10)
print '%s/%s = %s' %(a,b, floor(a,b))
n -= 1
```

Output:

```11/4 = 2
3/5 = 0
11/5 = 2
10/1 = 10
-6/9 = -1
14/2 = 7
-4/7 = -1
8/6 = 1
7/1 = 7
-7/1 = -7
-20/5 = -4
11/4 = 2
16/10 = 1
-9/7 = -2
-7/6 = -2
-8/2 = -4
13/7 = 1
-3/2 = -2
-10/2 = -5
-6/1 = -6```

## Fetching every other item in the list

Q1: How do you fetch every other item in the list?

Suppose we have a list like this:

```>>> L = [x*10 for x in range(10)]
>>> L
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
```
1. We can use enumerate(L) to get indexed series:
```>>> for i,v in enumerate(L):
...    if i % 2 == 0:
...       print v,
...
0 20 40 60 80
```
2. This one may be the simplest solution:
```L2 = L[::2]
>>> L2
[0, 20, 40, 60, 80]```

## Python type() – function

What’s get printed?

```def f():
pass
print type(f())
print type(1J)
print 1j*1j
print type(lambda:None)
```

```<type 'NoneType'>
<type 'complex'>
(-1+0j)
<type 'function'>
```
1. The argument to the type() call is a return value of a function call, which returns None.
2. ‘lambda arguments: expression’ yields a function object.
3. An imaginary literal yields a complex number with a real part of 0.0.

## Dictionary Comprehension

Q2: What’s the list comprehension? How about dictionary comprehension?
Construct x^3 from a list of integers, L = [0,1,2,3,4,5]

List comprehension:

```>>> L2 = [x**3 for x in L]
>>> L2
[0, 1, 8, 27, 64, 125]
```

Or:

```>>> L2 = [x**3 for x in range(6)]
>>> L2
[0, 1, 8, 27, 64, 125]
```

Dictionary comprehension:

```>>> D1 = dict((k,k**3) for k in L)
>>> D1
{0: 0, 1: 1, 2: 8, 3: 27, 4: 64, 5: 125}
```

Or for Python 3:

```>>> D2 = {k:k**3 for k in L}
>>> D2
{1: 1, 2: 8, 3: 27}```

## Sum

Q3: Sum of all elements in a list ([1,2,3,…,100] with one line of code.

```>>> Ans = sum(range(101))
>>> Ans
5050
```

Q3.b: How about summing only odd elements?

```>>> sum(range(1,101,2))
```

Or:

```>>> Ans = sum(x for x in range(101) if x % 2 != 0)
>>> Ans
2500
```

Or:

```>>> Ans = reduce(lambda x,y: x+y, filter(lambda x: x % 2 != 0, range(1,101)))
>>> Ans
2500
```

Or

`>>> sum(filter(lambda x: x % 2, range(1,101)))`

## Truncating division

Two divisions – ‘/’ and ‘//’:

```>>> 5.5/2
2.75
>>> 5.5//2
2.0```

## Python 2 vs Python 3

Q: What are the differences between Python 2 and Python 3?

Please visit Python 2 vs Python 3.

## len(set)

What’s the output?

```>>> len(set([1,1,2,3,3,3,4]))
```

Output:

```4
```

set() only retains unique values.

We want to print a list of files in a directory including the sub-directories. We may want to do it recursively.

```import os

def file_list(dir):
basedir = dir
subdir_list = []
for item in os.listdir(dir):
fullpath = os.path.join(basedir,item)
if os.path.isdir(fullpath):
subdir_list.append(fullpath)
else:
print fullpath

for d in subdir_list:
file_list(d)

file_list('/dir')
```

Output:

```./d3/f1
./d3/d4/d7/f2
./d3/d4/d7/f3
./d3/d5/d9/d10/f4
./d3/d5/d9/d10/f5```

## Count occurrence of a character in a Python string

For a given sentence, for example, “The Mississippi River”, count the occurrence of a character in the string.

```sentence='The Mississippi River'

def count_chars(s):
s=s.lower()
count=list(map(s.count,s))
return (max(count))

print count_chars(sentence)
```

Let’s look into the code, count=list(map(s.count,s))

```>>> count = map(s.count,s)
>>> count
[1, 1, 2, 2, 1, 5, 4, 4, 5, 4, 4, 5, 2, 2, 5, 2, 1, 5, 1, 2, 1]
```

Actually, the each item in the list output represents the occurrence of each character including space:

``` T  h  e     M  i  s  s  i  s  s  i  p  p  i     R  i  v  e  r
[1, 1, 2, 2, 1, 5, 4, 4, 5, 4, 4, 5, 2, 2, 5, 2, 1, 5, 1, 2, 1]
```

In the line, map(func, sequence), the s.count counts the occurrence of a character while it iterates the character sequence of s.

Or

```sentence='The Mississippi River'

def count_chars(s):
s=s.lower()
L = [s.count(c) for c in s]
return max(L)

print (count_chars(sentence))
```

Or we can use dictionary:

```sentence='The Mississippi River'
sl = sentence.lower()

d = {}.fromkeys([x for x in sl],0)

for char in sl:
d[char] += 1

print d
```

Output:

```{' ': 2, 'e': 2, 'i': 5, 'h': 1, 'm': 1, 'p': 2, 's': 4, 'r': 2, 't': 1,
'v': 1}
```

Or we can use dict.get(key,None) method:

```sentence='The Mississippi River'
sl = sentence.lower()
d = {}
for c in sl:
d[c] = d.get(c,0) + 1
print d
```

Output:

```{' ': 2, 'e': 2, 'i': 5, 'h': 1, 'm': 1, 'p': 2, 's': 4, 'r': 2, 't': 1, 'v': 1}
```

Or we can use dictionary comprehension:

```sentence = "The Mississippi River"
ans = dict((c,sentence.count(c)) for c in sentence)
print ans
```

Output:

```{' ': 2, 'e': 2, 'i': 5, 'h': 1, 'M': 1, 'p': 2, 's': 4, 'R': 1, 'T': 1, 'v': 1, 'r': 1}
```

## Make a prime number list from (1,100)

```import math
def isPrime(n):
if n <= 1:
return False
if n == 2:
return True
if n % 2 == 0:
return False
for t in range(3, int(math.sqrt(n)+1),2):
if n % t == 0:
return False
return True

print [n for n in range(100) if isPrime(n)]
```

Output:

```[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
```

A simpler code:

```def isPrime(n):
if n == 1:
return False
for t in range(2,n):
if n % t == 0:
return False
return True

print [n for n in range(1,100) if isPrime(n)]
```

Not much but a little bit of tweak: generate a list with the first 100 primes:

```import math
def isPrime(n):
if n == 1:
return False
elif n == 2:
return True
elif n % 2 == 0:
return False
else:
for t in range(3, int(math.sqrt(n)+1), 2):
if ( n % t == 0 ):
return False
return True

count = 1
n = 1
primes = []
while (count <= 100):
if isPrime(n):
primes.append(n)
count += 1
n += 1

print primes
```

Run it:

```\$ python prime2.py
python prime.py
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541]```

## Reversing a string – Recursive

When it comes to reversing a string in python, we do have s[::-1], boring!

In the following recursive code, at every call, the first string will go to the end and stored in stack. So, when there is only one character left as an input string, the code starts rewind and retrieve the character one by one. The net effect is it gets the character in reverse. It becomes obvious when we see the printed output below:

```def reverse(input):
print input
if len(input) <= 1:
return input

return reverse(input[1:]) + input[0]

s = 'reverse'
print(reverse(s))
```

Output:

```reverse
everse
verse
erse
rse
se
e
esrever
```

## Reversing a string – Iterative

In the code below, we use range index operation, putting the characters into the list in reverse order. Than we pack them using join():

```def reverse(input):
return ''.join([input[i] for i in range(len(input)-1, -1, -1)])

s = 'reverse'
print(reverse(s))
```

In the range() function, we used “-1” as a “stop” index and another “-1” as a “step” size.

Output:

```esrever
```

## Output?

Q: What’s the output from the following code?

```def f():
yield

def g():
return

print 'f()=', f()
print 'g()=', g()
```

You can find the answer from generator.send() method.

## Merging overlapped range

Q: We have a list of tuples where each tuple is a (start, end). We want to merge all overlapping ranges and return a list of distinct ranges. For example:

```[(1, 5), (2, 4), (3, 6)] --->  [(1, 6)]
[(1, 3), (2, 4), (5, 6)] --->  [(1, 4), (5, 6)]
```

Write a code to produce a list of tuples with distinct ranges. Try with this data:

```L = [(4,9), (20, 22), (1, 3), (24, 32), (23, 31), (40,50), (12, 15), (8,13)]
```

Here is the code:

```L = [(4,9), (20, 22), (1, 3), (24, 32), (23, 31), (40,50), (12, 15), (8,13)]
# L = [(1, 5), (2, 4), (3, 6)]
# L = [(1, 3), (2, 4), (5, 6)]
L = sorted(L)
print L

Lnew = []
st = L[0][0]
end = L[0][1]

for item in L[1:]:
if end >= item[0]:
if end < item[1]:
end = item[1]
else:
Lnew.append((st,end))
st = item[0]
end = item[1]

Lnew.append((st,end))

print Lnew
```

Output:

```[(1, 3), (4, 9), (8, 13), (12, 15), (20, 22), (23, 31), (24, 32), (40, 50)]
[(1, 3), (4, 15), (20, 22), (23, 32), (40, 50)]
```

## Conditional expressions (ternary operator)

Q: Outputs the result using ternary operator. ‘pass’ when the ‘expected’ is the same as ‘returned’, otherwise outputs ‘fail’. Assume ‘expected’ = 1, ‘returned’ = 0.

```expected = 1
returned = 0
result = 'pass' if expected == returned else 'fail'
print result
```

## Function args

What will printed?

```def getThem(arg1, *arg2):
print type(arg2), arg2

getThem('uno','dos','tres','cuatro','cinco')
```

arg2 aggregates the rest of args into a tuple. So, the output should look like this:

```<type 'tuple'> ('dos', 'tres', 'cuatro', 'cinco')
```

```def getThem(arg1, **arg2):
print type(arg2), arg2

getThem('numbers',one='uno',two='dos',three='tres',four='cuatro',five='cinco')
```

arg2 aggregates the remaining parameters into a dictionary. So, the output is:

```<type 'dict'> {'four': 'cuatro', 'three': 'tres', 'five': 'cinco', 'two': 'dos', 'one': 'uno'}
```

## Unpacking args

Will the code below work?

```def getThem(a,b,c,d,e):
print a,b,c,d,e

mList = ['uno','dos','tres','cuatro','cinco']
getThem(mList)
```

We’ll get an error:

```TypeError: getThem() takes exactly 5 arguments (1 given)
```

So, the code should be changed like this:

```getThem(*mList)
```

*mList will unpack the list into individual elements to be passed to the function.

The unpacking a list can also be used as this:

```>>> a, *b, c = [1,2,3,4,5,6,7,8,9,10]
>>> print(b)
[2, 3, 4, 5, 6, 7, 8, 9]

>>> a, *b, c, d = [1,2,3,4,5,6,7,8,9,10]
>>> print(b)
[2, 3, 4, 5, 6, 7, 8]
```

## Finding the 1st revision with a bug

We have (oth-7th) revisions committed to Github, and due to a testing flaw, at the 7th revision we found that a bug has been introduced. We want to find when it was committed:

```# r0 r1 r2 r3 r4 r5 r6 r7
# G  ?  ?  ?  ?  ?  ?  B   (G: good, B: buggy)
```

We may want to use binary search: if found bug, move backwards (previous rev.), if not, mode forwards (later rev.). In the code sample below, we’re testing 6 cases:

```def hasBug(i):
if rev[i] == 'B':
return True
return False

st = good
ret = -1
mid = (st + end) / 2
while (mid > good and mid < bad):
# backwards
if hasBug(mid):
end = mid
ret = mid
if mid == good + 1: break
# forwards
else:
st = mid
if mid == end - 1: break
mid = (st + end ) / 2

return ret

if __name__ == "__main__":
rev = ['G','B','B','B','B','B','B','B']
print 1 == find_bug(0,7)

rev = ['G','G','B','B','B','B','B','B']
print 2 == find_bug(0,7)

rev = ['G','G','G','B','B','B','B','B']
print 3 == find_bug(0,7)

rev = ['G','G','G','G','B','B','B','B']
print 4 == find_bug(0,7)

rev = ['G','G','G','G','G','B','B','B']
print 5 == find_bug(0,7)

rev = ['G','G','G','G','G','G','B','B']
print 6 == find_bug(0,7)
```

Note that the find_bug() function returns the first revision # that introduced a bug.

Output:

```True
True
True
True
```

## Which one has higher precedence in Python? – NOT, AND , OR

What will be printed out?

```>>> True or False and False
```

Since AND is higher precedence than OR, AND will be evaluated first, “True” will be printed out.

```>>> not True or False or not False and True
True
```

NOT has first precedence, then AND, then OR.

## Decorator(@) 1 – with dollar sign(\$)

We have a function that returns the amount with tax added. We want to prefix the amount with a dollar(\$) using decorator:

```@dollar
def price(amount, tax_rate):
return amount + amount*tax_rate
```

How do we want to implement the decorator function, dollar()?

Here is the code:

```def dollar(fn):
def new(*args):
return '\$' + str(fn(*args))
return new

@dollar
def price(amount, tax_rate):
return amount + amount*tax_rate

print price(100,0.1)
```

Output:

```\$110
```

Note that we did not modify the decorated function, price(), at all.

## Decorator(@) 2 – Basic

This example is not much different from the previous one.

We have a function returning squared number:

```def oldFnc(n):
return n*n
```

Write a code doubling the return value from oldFnc() just by adding a decorator like this:

```@doubleIt
def oldFnc(n):
return n*n
```

Here is a code:

```def doubleIt(myfnc):
def doubleItInside(*args):
return myfnc(*args)*2
return doubleItInside

@doubleIt
def oldFnc(n):
return n*n

#oldFnc = doubleIt(oldFnc)

print oldFnc(5)```

## Multi-line coding

The following code won’t print out properly. What’s wrong with the code?

```days = ['Monday',
'Tuesday',
'Wednesday']

months = ['Jan', \
'Feb', \
'Mar']

print "DAYS: %s, MONTHS %s" %
(days, months)
```

days is OK because expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. The months is also OK because backslashes are used to join physical lines, even though they are not required in this case. The print statement will not print the data because 2 logical lines are used without a backslash to join them into a logical line.

So, correct code should look like this:

```print "DAYS: %s, MONTHS %s" %\
(days, months)```

## Recursive binary search

Recursive binary serach:

```# returns True if found the item
# otherwise, returns False
def bSearch(a, item):
if len(a) == 0:
return False
mid = len(a)/2
if a[mid] == item:
return True
else:
if a[mid] < item:
return bSearch(a[mid+1:], item)
else:
return bSearch(a[:mid], item)

if __name__ =="__main__":
a = [1,3,4,5,8,9,17,22,36,40]
print bSearch(a, 9)
print bSearch(a, 10)
print bSearch(a, 36)
```

Output:

```True
False
True```

## Iterative binary search

Iterative binary serach:

```# returns True if found the item
# otherwise, returns False
def bSearch(a, item):
st = 0
end = len(a)-1
mid = len(a)/2
left = st
right = end
while True:
# found
if a[mid] == item:
return True
# upper
elif a[mid] < item:
left = mid + 1
# lower
else:
right = mid - 1

mid = (left+right)/2
if mid < st or mid > end: break
if left == right and a[mid] != item: break
return False

if __name__ =="__main__":
a = [1,3,4,5,8,9,17,22,36,40]
print bSearch(a, 9)
print bSearch(a, 10)
print bSearch(a, 36)
print bSearch(a, 5)
print bSearch(a, 22)
```

Output:

```True
False
True
True
True```

## Pass by reference

List is passed by reference to the function and modifications to the function parameter also effect the original list.

What’s the size of the list, (len(mList)).

```def addItem(l):
l += [0]

mList = [1, 2, 3, 4]
print len(mList)```

## Simple calculator

This is not a real calculator. It’s a practice of stack implementation by manipulating list’s pop() and append().

The code should pass the following test:

```test = {"11++":-1, "1+2": -1, "12+":3, "12+4*":12, "12+4*5+":17, "42-5*7-":3}
```

The keys are the question strings, and the values are the correct answers.

Note the following:

1. We should have at least two items in the list whenever we see ‘+’/’-‘/’*’ operators. Otherwise, it should issue -1 and exit.
2. For ‘-‘ operation, we need to take care of the the order of pop() operation. In the code, we prepend ‘-‘ for the last item in the list and then pops the 2nd to the last after that.

Here is the code:

```def sol(input):
a = []
print "input=",input
for c in input:
if c.isdigit():
a.append(c)
elif c == '+':
if len(a) < 2:
return -1
a.append(int(a.pop())+int(a.pop()))
elif c == '-':
if len(a) < 2:
return -1
a.append(-int(a.pop())+int(a.pop()))
elif c == '*':
if len(a) < 2:
return -1
a.append(int(a.pop())*int(a.pop()))
else:
pass
return a[0]

test = {"11++":-1, "1+2": -1, "12+":3, "12+4*":12, "12+4*5+":17, "42-5*7-":3}

for k,v in test.items():
if sol(k) == v:
print k, v, 'Passed'
print
else:
print k, v, 'Error'
print
```

Output:

```input= 12+4*
12+4* 12 Passed

input= 42-5*7-
42-5*7- 3 Passed

input= 11++
11++ -1 Passed

input= 12+
12+ 3 Passed

input= 12+4*5+
12+4*5+ 17 Passed

input= 1+2
1+2 -1 Passed```

## iterator class that returns network interfaces

Write a class that returns network interfaces (eth0, wlan0, …).

Use subprocess and ip link show command.

```import subprocess

class interfaces:
def __init__(self):
self.intf = []
proc = subprocess.Popen(['ip', 'link', 'show'], stdout=subprocess.PIPE)
line_count = 0
while True:
if line != '':
if line_count % 2 == 0:
self.intf.append(line)
else:
break
line_count += 1
self.counter = -1
self.max = len(self.intf)

def __iter__(self):
return self

def next(self):
if self.counter >= self.max-1:
raise StopIteration
self.counter += 1
return self.intf[self.counter]

f = interfaces()
for i in f:
print i
```

Note that we used next() instead of __next__() because we’re using Python 2.

Output:

```1: lo: <loopback,up,lower_up> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default

2: eth0: <no-carrier,broadcast,multicast,up> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000

3: wlan0: <broadcast,multicast,up,lower_up> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000

4: lxcbr0: <broadcast,multicast,up,lower_up> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default

5: docker0: <no-carrier,broadcast,multicast,up> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default

8: vmnet1: <broadcast,multicast,up,lower_up> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000

9: vmnet8: <broadcast,multicast,up,lower_up> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000

## Converting domain to ip

We have a file that lists domain names. We want to write a Python function that takes the file and returns a dictionary that has a key for the domain and a value for ip.

For example, the input file (‘domains.txt’) looks like this:

```google.com
yahoo.com
```

Output is:

```{'yahoo.com': '98.139.183.24', 'google.com': '216.58.192.14'}
```

Hint: we may want to use dig command, and to make the output simpler (only want to get ANSWER section), we can use it with additional options: +noall and +answer.

Here is the code:

```import subprocess

def getIPs(file):
ips = {}
with open(file) as f:
for line in f:
domain = line.strip()
out = subprocess.check_output(["dig","+noall","+answer", domain])
ips[domain] = out.split()[4]
return ips

print getIPs('domains.txt')```

## How to count the number of instances

We have a class A, and we want to count the number of A instances.

Hint : use staticmethod

```class A:
total = 0

def __init__(self, name):
self.name = name
A.total += 1

def status():
print "Total number of instance of A : ", A.total
status = staticmethod(status)

a1 = A("A1")
a2 = A("A2")
a3 = A("A3")
a4 = A("A4")

A.status()
```

Output:

```Total number of instance of A :  4
```

We can use decorator (@staticmethod) like this:

```   @staticmethod
def status():
print "Total number of instance of A : ", A.total```

## Python profilers – cProfile

cProfile and profile provide deterministic profiling of Python programs. A profile is a set of statistics that describes how often and for how long various parts of the program executed.

We can find the explanation of the output from the reference:

In the output from fibo(10), the first line indicates that 21893 calls were monitored. Of those calls, 3 were primitive, meaning that the call was not induced via recursion. The next line: Ordered by: standard name, indicates that the text string in the far right column was used to sort the output. The column headings include:

1. ncalls
for the number of calls
2. tottime
for the total time spent in the given function (and excluding time made in calls to sub-functions)
3. percall
is the quotient of tottime divided by ncalls
4. cumtime
is the cumulative time spent in this and all subfunctions (from invocation till exit). This figure is accurate even for recursive functions.
5. percall
is the quotient of cumtime divided by primitive calls
6. filename:lineno(function)
provides the respective data of each function

When there are two numbers in the first column (for example 21891/1), it means that the function recursed. The second value is the number of primitive calls and the former is the total number of calls. Note that when the function does not recurse, these two values are the same, and only the single figure is printed.

## Calling a base class method from a child class that overrides it

The super() can be used when the root class inherits from the object class, and here is the code of calling a base class method from a child class that overrides it:

## How do we find the current module name?

A module can find out its own module name by looking at the predefined global variable __name__. If this has the value ‘__main__’, the program is running as a script.

Many modules that are usually used by importing them also provide a command-line interface or a self-test, and only execute this code after checking __name__:

```# t.py
def f():
print ('module name is %s' % __name__)

if __name__ == '__main__':
f()
```

Run it as a script:

```\$ python t.py
module name is __main__
```

If we import the t.py, the module name will be t:

```\$ python s.py
module name is t```

## Why did changing list ‘newL’ also change list ‘L’?

We might be wondering why appending an element to newL changed L too.

There are two factors that produce this result:

1. Variables are simply names that refer to objects. Doing newL = L doesn’t create a copy of the list – it creates a new variable newL that refers to the same object L refers to. This means that there is only one object (the list), and both L and newL refer to it.
2. Lists are mutable, which means that we can change their content.

Please check: Copy an object

## Construction dictionary – {key:[]}

We have a list of numbers, and we want to group them by the number of digits:

```numbers = [1,256,64,65536,186000,1024,8,16,1905]
d = {}
for n in numbers:
d.setdefault(len(str(n)),[]).append(n)
print d
```

Output:

```{1: [1, 8], 2: [64, 16], 3: [256], 4: [1024, 1905], 5: [65536], 6: [186000]}
```

## Colon separated sequence

Write a program which will find all such numbers which are divisible by 7 but are not a multiple of 3, between 1 and 100 (both included). The numbers obtained should be printed in a colon(:)-separated sequence on a single line as shown below:

```7:14:28:35:49:56:70:77:91:98
```

The code should look like this:

```l = []
for n in range(1,101):
if n % 7 == 0 and n % 3 != 0:
l.append(str(n))
print ':'.join(l)```

## Converting binary to integer

We want to convert binary numbers to integers:

```"0100,0011,1010,1001" => [4, 3, 10, 9]
```

Here is the code:

```s1 = "0100,0011,1010,1001"
s2 = s1.split(',')
num = []
for s in s2:
n = 0
for i,v in enumerate(s[::-1]): # reverse 0100->0010
n += (2**int(i)) * int(v)
num.append(n)
print num```

## 9+99+999+9999+…

We want to write a code that computes the value of a+aa+aaa+aaaa with a given digit as the value of a. Suppose the following input is supplied to the program:

```N = 9
DIGIT = 4
```

Then, the output should be:

```9+99+99+9999 = 11106
```

Here is the code:

```N = 9
DIGIT = 4
s = 0
for i in range(1,DIGIT+1):
s += int(str(N)*i) # '9'*3 = '999'
print s
```

## Calculating balance

We have a file that has deposit(D) and withdrawal(W) records:

```D 500
D 300
W 100
D 400
W 100
```

We want to calculate the balance after reading the bank records, and it should be 1,000. The code looks like this:

```f = open("bank.txt")
balance = 0
for line in f:
item = line.rstrip().split()
if item[0] == 'D':
balance += int(item[1])
else:
balance -= int(item[1])
print balance
f.close()```

## Regular expression – findall

We can take only the words composed of digits from a given string using re.findall():

```s = """Solar system:
Planets 8
Dwarf Planets: 5
Moons: Known = 149 | Provisional = 24 | Total = 173
Comets: More than 3400
Asteroids: More than 715000"""

import re
d = re.findall('\d+',s)
print d
```

Output:

```['8', '5', '149', '24', '173', '3400', '715000']
```

## Chickens and pigs

We have a count of 35 heads and 94 legs among the chickens and pigs in a farm. How many pigs and how many chickens do we have?

```# 35 heads and 94 legs among the chickens and pigs
# c + p = 35
# 2*c + 4*p = 94
legs = 94
for c in range(heads):
p = 35-c
if 2*c + 4*p == 94:
print c,p
```

`23 12`

## Highest possible product

Find the highest possible product that we can get by multiplying any 3 numbers from an input array:

```def mx3(a):
b = sorted(a)

m0 = b[0]
m1 = b[1]
x1 = b[-1]
x2 = b[-2]
x3 = b[-3]

if m0 < 0 and m1 < 0:
return max(m0*m1*x1,x1*x2*x3)

else:
return x1*x2*x3

l1 = [10,20,5,2,7,9,3,4]
l2 = [10,-20,5,2,7,9,3,4]
l3 = [-10,-20,5,2,7,9,-3,4]
l4 = [10,-20,5,2,7,9,-3,4]

print mx3(l1)
print mx3(l2)
print mx3(l3)
print mx3(l4)
```

Output:

```1800
630
1800
630```