Scratchpad 2019 12 02

Day 1


In [1]:
a = 1
a


Out[1]:
1

In [2]:
a = "ciao"
a


Out[2]:
'ciao'

In [3]:
a = []
a.append(1)
a


Out[3]:
[1]

In [4]:
print(dir(__builtins__))


['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '__IPYTHON__', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'display', 'divmod', 'enumerate', 'eval', 'exec', 'filter', 'float', 'format', 'frozenset', 'get_ipython', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

In [5]:
t = (1,2,3,4,5)
t


Out[5]:
(1, 2, 3, 4, 5)

In [6]:
xs = [1,2,3,4,5]
xs


Out[6]:
[1, 2, 3, 4, 5]

In [7]:
xs[2] = 10
xs


Out[7]:
[1, 2, 10, 4, 5]

In [8]:
dir(xs)


Out[8]:
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__delitem__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__gt__',
 '__hash__',
 '__iadd__',
 '__imul__',
 '__init__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__reversed__',
 '__rmul__',
 '__setattr__',
 '__setitem__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'append',
 'clear',
 'copy',
 'count',
 'extend',
 'index',
 'insert',
 'pop',
 'remove',
 'reverse',
 'sort']

In [9]:
help(xs)


Help on list object:

class list(object)
 |  list() -> new empty list
 |  list(iterable) -> new list initialized from iterable's items
 |  
 |  Methods defined here:
 |  
 |  __add__(self, value, /)
 |      Return self+value.
 |  
 |  __contains__(self, key, /)
 |      Return key in self.
 |  
 |  __delitem__(self, key, /)
 |      Delete self[key].
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(...)
 |      x.__getitem__(y) <==> x[y]
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __iadd__(self, value, /)
 |      Implement self+=value.
 |  
 |  __imul__(self, value, /)
 |      Implement self*=value.
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __mul__(self, value, /)
 |      Return self*value.n
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __reversed__(...)
 |      L.__reversed__() -- return a reverse iterator over the list
 |  
 |  __rmul__(self, value, /)
 |      Return self*value.
 |  
 |  __setitem__(self, key, value, /)
 |      Set self[key] to value.
 |  
 |  __sizeof__(...)
 |      L.__sizeof__() -- size of L in memory, in bytes
 |  
 |  append(...)
 |      L.append(object) -> None -- append object to end
 |  
 |  clear(...)
 |      L.clear() -> None -- remove all items from L
 |  
 |  copy(...)
 |      L.copy() -> list -- a shallow copy of L
 |  
 |  count(...)
 |      L.count(value) -> integer -- return number of occurrences of value
 |  
 |  extend(...)
 |      L.extend(iterable) -> None -- extend list by appending elements from the iterable
 |  
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value.
 |      Raises ValueError if the value is not present.
 |  
 |  insert(...)
 |      L.insert(index, object) -- insert object before index
 |  
 |  pop(...)
 |      L.pop([index]) -> item -- remove and return item at index (default last).
 |      Raises IndexError if list is empty or index is out of range.
 |  
 |  remove(...)
 |      L.remove(value) -> None -- remove first occurrence of value.
 |      Raises ValueError if the value is not present.
 |  
 |  reverse(...)
 |      L.reverse() -- reverse *IN PLACE*
 |  
 |  sort(...)
 |      L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __hash__ = None


In [10]:
s = "ciao"
s[1]


Out[10]:
'i'

In [11]:
for x in xs:
    print(x)


1
2
10
4
5

In [12]:
for c in s:
    print(c)


c
i
a
o

In [13]:
t[1:3]


Out[13]:
(2, 3)

In [14]:
t[-1]


Out[14]:
5

In [15]:
t[::2]


Out[15]:
(1, 3, 5)

In [16]:
t[1::2]


Out[16]:
(2, 4)

In [17]:
t1, t2 = t[::2], t[1::2]

In [18]:
t1


Out[18]:
(1, 3, 5)

In [19]:
t2


Out[19]:
(2, 4)

In [20]:
integers, strings = 1, "ciao"

In [21]:
integers


Out[21]:
1

In [22]:
strings


Out[22]:
'ciao'

In [23]:
xs[::2]


Out[23]:
[1, 10, 5]

In [24]:
xs


Out[24]:
[1, 2, 10, 4, 5]

In [25]:
len(xs)


Out[25]:
5

In [26]:
tuple("ciao")


Out[26]:
('c', 'i', 'a', 'o')

In [27]:
tuple(xs)


Out[27]:
(1, 2, 10, 4, 5)

In [28]:
list("ciao")


Out[28]:
['c', 'i', 'a', 'o']

In [29]:
ys = [1,2,3,4,5,6,7,8,9,10]

In [30]:
yh1, yh2 = ys[:5], ys[5:]

In [31]:
yh1


Out[31]:
[1, 2, 3, 4, 5]

In [32]:
yh2


Out[32]:
[6, 7, 8, 9, 10]

In [33]:
t1 = 1,2,3
t2 = 4,5
t1 * 2


Out[33]:
(1, 2, 3, 1, 2, 3)

In [34]:
tt = (1, 10.0, "ciao")
tt[2]


Out[34]:
'ciao'

In [35]:
i, f, s = tt
f


Out[35]:
10.0

Hints for Code Jam

Open a file


In [36]:
with open("input.txt") as a_file:
    for line in a_file:
        print(line.strip())


2
3
1 3 -5
-2 4 1
5
1 2 3 4 5
1 0 1 0 1

Calculate permutations


In [37]:
from itertools import permutations
for p in permutations([1,2,3]):
    print(p)


(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)

Sorting a list "inplace"


In [38]:
r = [3,5,2,1,0]
r.sort()
r


Out[38]:
[0, 1, 2, 3, 5]

In [39]:
r.sort(reverse=True)
r


Out[39]:
[5, 3, 2, 1, 0]

Split a string and transform to integer


In [40]:
x = "1 2 3"

In [41]:
ints = [int(xi) for xi in x.split()]
ints


Out[41]:
[1, 2, 3]

Iterate on two lists


In [42]:
for x, y in zip([1,2,3], [4,5,6]):
    print(x, y)


1 4
2 5
3 6

Prinf a formatted text


In [43]:
s = "Case#{}: {}".format(1, -25)
s


Out[43]:
'Case#1: -25'

Sets


In [44]:
myset = set([1,1,1,3,3,4,5,6,6])
myset


Out[44]:
{1, 3, 4, 5, 6}

In [45]:
for elem in myset:
    print(elem)


1
3
4
5
6

In [46]:
3 in myset


Out[46]:
True

In [47]:
7 in myset


Out[47]:
False

In [48]:
another_set = set([1,2,8,9,7])

In [49]:
myset | another_set


Out[49]:
{1, 2, 3, 4, 5, 6, 7, 8, 9}

In [50]:
myset & another_set


Out[50]:
{1}

In [51]:
myset - another_set


Out[51]:
{3, 4, 5, 6}

In [52]:
another_set - myset


Out[52]:
{2, 7, 8, 9}

In [53]:
myset ^ another_set


Out[53]:
{2, 3, 4, 5, 6, 7, 8, 9}

In [54]:
myset > another_set


Out[54]:
False

Strings


In [55]:
ss = "L'uno"
ss


Out[55]:
"L'uno"

In [56]:
ss = '"virgolettato"'
ss


Out[56]:
'"virgolettato"'

In [57]:
ss = """ Si puo' mettere "tutto" """
ss


Out[57]:
' Si puo\' mettere "tutto" '

In [58]:
ss[3]


Out[58]:
' '

In [59]:
ss * 3


Out[59]:
' Si puo\' mettere "tutto"  Si puo\' mettere "tutto"  Si puo\' mettere "tutto" '

In [60]:
ss.split()


Out[60]:
['Si', "puo'", 'mettere', '"tutto"']

In [61]:
','.join(ss.split())


Out[61]:
'Si,puo\',mettere,"tutto"'

Dicts


In [62]:
d = {}
help(d.setdefault)


Help on built-in function setdefault:

setdefault(...) method of builtins.dict instance
    D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D


In [63]:
for n, elem in enumerate([1,5,6,7,2,3]):
    print(n, elem)


0 1
1 5
2 6
3 7
4 2
5 3

In [64]:
for a,b in zip([1,2,3], ["a", "b", "c"]):
    print(a, b)


1 a
2 b
3 c

In [65]:
enu = enumerate([1,5,6,7,2,3])
type(enu)


Out[65]:
enumerate

In [66]:
import collections

def mydefval():
    return "a default"

def_dict = collections.defaultdict(mydefval)
def_dict['hello']
def_dict


Out[66]:
defaultdict(<function __main__.mydefval()>, {'hello': 'a default'})

Python Language


In [67]:
range(10)


Out[67]:
range(0, 10)

In [68]:
sorted('abracadabra')


Out[68]:
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r']

In [69]:
reversed('abracadabra')


Out[69]:
<reversed at 0x1103916a0>

In [70]:
d = {'a': 1, 'b':2}
d.items()


Out[70]:
dict_items([('a', 1), ('b', 2)])

In [71]:
for k, v in d.items():
    print((k, v))


('a', 1)
('b', 2)

If we want a dict where insertion order holds, is necessary to use a OrderedDict


In [72]:
d = collections.OrderedDict()
d['a'] = 1
d['b'] = 2
for k, v in d.items():
    print(k ,v)


a 1
b 2

From Python 3.7 built-in dict is insertion ordered

Question: what if I want to navigate a dict sorted in some way? Use sorted


In [73]:
stocks = {"CSCO": 45, "APPL": 104, "IBM": 89}
sorted(stocks.items())


Out[73]:
[('APPL', 104), ('CSCO', 45), ('IBM', 89)]

In [74]:
sorted(stocks.items(), key=lambda x: x[1])


Out[74]:
[('CSCO', 45), ('IBM', 89), ('APPL', 104)]

In [75]:
sorted(stocks.items(), key=lambda x: -x[1])


Out[75]:
[('APPL', 104), ('IBM', 89), ('CSCO', 45)]

Exception


In [76]:
try:
    1/0
except ZeroDivisionError:
    print("Zero")
except Exception:
    print("Base")


Zero

OOP

Private access modifier is __ (double underscore), protected is _ but is only a convention.


In [77]:
class Person:
    def __init__(self, name, alias):
        self.name = name
        self.__alias = alias

    def who(self):
        "Public"
        return self.name + " " + self.__alias
        
    def _who(self):
        "Protected. Is only a convention."
        return self.who() + " is a superhero!"
    
    def __who(self):
        "Private"
        return self._who() + " His girl friend is Mary Jane!!"

peter = Person("peter", "spiderman")
print(peter.name)
print(peter.who())
# peter.__alias
# AttributeError: 'Person' object has no attribute '__alias'
print(peter._who())
# peter.__who()
# AttributeError: 'Person' object has no attribute '__who'
# If you really want to call a private field/attribute
peter._Person__who()


peter
peter spiderman
peter spiderman is a superhero!
Out[77]:
'peter spiderman is a superhero! His girl friend is Mary Jane!!'