spam = 65              # an integer declaration. Yes, no semicolon ; at the end
print spam             # print is a reserved keyword / statement

print type(spam)       # this is a functional call

eggs = 2
print eggs
print type(eggs)

"""
Explanation: Numbers
End of explanation
"""


print spam + eggs      # sum

print spam - eggs      # difference

print spam * eggs      # product

print spam / eggs      # quotient

print spam // eggs     # floored quotient

print spam % eggs      # remainder or module

print pow(spam, eggs)  # power (yes, this is how a funtion is called)

print spam ** eggs     # power

fooo = -2              # negative value
print fooo
print type(fooo)

print -fooo            # negated

print +fooo            # unchanged

print abs(fooo)        # absolute value

print int(fooo)        # convert to integer

print long(fooo)       # convert to long integer

print float(fooo)      # convert to float

fooo += 1              # autoincremental (there is no ++)
print fooo

# More on the quotient

print spam / eggs          # quotient
print spam / float(eggs)   # quotient
print spam // float(eggs)  # floored quotient, aka. integer division

# More on the operations result type

print type(spam + eggs)
print type(long(spam) + eggs)
print type(float(spam) + eggs)
print type(float(spam) + long(eggs))

"""
Explanation: Let's see the numeric operations
End of explanation
"""


# Let's try again the power

print eggs ** spam
print type(eggs ** spam)

from sys import maxint
print maxint

# Let's instantiate other values

spam = 65L             # a long
print spam
print type(spam)

eggs = 2.0             # a float
print eggs
print type(eggs)

spam = 0101             # an integer in octet
print spam
print type(spam)

spam = 0x41            # an integer in hexadecimal
print spam
print type(spam)

# Let's do more complex operations

print round(spam + eggs / spam, 3)    # round to n digits, 0 by default
print round((spam + eggs) / spam, 3)  # round to n digits, 0 by default
print round(spam + (eggs / spam), 3)  # round to n digits, 0 by default

"""
Explanation: Python automatically infers the type of the result depending on operands type
End of explanation
"""


spam = "spam"                    # a string
print spam
print type(spam)

eggs = '"eggs"'                  # another string
print eggs
print type(eggs)

eggs = '\'eggs\''                # another string
print eggs

spam_eggs = "'\tspam\n\teggs'"   # another string
print spam_eggs
print type(spam_eggs)

"""
Explanation: Use parentheses to alter operations order
SOURCES
http://docs.python.org/2/library/stdtypes.html#numeric-types-int-float-long-complex
STRINGS
End of explanation
"""


spam_eggs = r"'\tspam\n\teggs'"  # a raw string
print spam_eggs
print type(spam_eggs)

"""
Explanation: Remember
String literal are written in ingle or double quotes. It's exactly the same
Backslash \ is the escape character
Escape sequences in strings are interpreted according to rules similar to those used by Standard C
End of explanation
"""


spam_eggs = u"'\tspam\n\teggs'"  # a unicode string
print spam_eggs
print type(spam_eggs)

"""
Explanation: Raw strings are prefixed with 'r' or 'R'
Raw strings use different rules for interpreting interpreting backslash escape sequences
End of explanation
"""


spam_eggs = u"'spam\u0020eggs'"  # a unicode string with Unicode-Escape encoding
print spam_eggs
print type(spam_eggs)

"""
Explanation: Unicode strings are prefixed with 'u' or 'U'
 - unicode is a basic data type different than str:
 - str is ALWAYS an encoded text (although you never notice it)
 - unicode use the Unicode character set as defined by the Unicode Consortium and ISO 10646. We could say unicode are encoding-free strings
 - str string literals are encoded in the default system encoding ( sys.getdefaultencoding() ) or using the encoding specified in modules encoding header
 - The module encoding header is set : #-- coding: utf-8 --
 - There is no way to fully check a string encoding (chardet module)
 - Depending on encoding used it is possible to operate with unicode and str together
End of explanation
"""


spam_eggs = """'\tspam
\teggs'"""                       # another string
print spam_eggs
print type(spam_eggs)

"""
Explanation: WARNING! Note that in Py3k this approach was radically changed:
 - All string literals are unicode by default and its type is 'str'
 - Encoded strings are specified with 'b' or 'B' prefix and its type is 'bytes'
 - Operations mixing str and bytes always raise a TypeError exception
End of explanation
"""


spam_eggs = "'\tspam" "\n\teggs'"  # another string
print spam_eggs
print type(spam_eggs)

"""
Explanation: Three single or double quotes also work, and they support multiline text
End of explanation
"""


spam_eggs = u"'\tspam\n \
\teggs'"  # a unicode string
print spam_eggs
print type(spam_eggs)

"""
Explanation: Several consecutive string literals are automatically concatenated, even if declared in different consecutive lines
Useful to declare too much long string literals
End of explanation
"""


spam = "spam"
eggs = u'"Eggs"'

print spam.capitalize()                    # Return a copy with first character in upper case

print spam

"""
Explanation: Let's see strings operations
End of explanation
"""


print spam.decode()                        # Decode the str with given or default encoding
print type(spam.decode('utf8'))

print eggs.encode()                        # Encode the unicode with given or default encoding
print type(eggs.encode('utf8'))

print spam.endswith("am")                  # Check string suffix (optionally use a tuple)

print eggs.startswith(("eggs", "huevos"))  # Check string prefix (optionally use a tuple)

print spam.find("pa")                      # Get index of substring (or -1)

print eggs.upper()
print eggs.lower()                         # Convert to upper or lower case

print spam.isupper()
print spam.islower()                       # Check if string is in upper or lower case

print repr(" | spam # ".strip())
print repr(" | spam # ".strip(' |#'))      # Remove leading and trailing characters (only whitespace by default)

print spam.isalpha()
print eggs.isalnum()
print spam.isdigit()                       # Check if string is numeric, alpha, both...

print repr(eggs)
print str(eggs)

"""
Explanation: WARNING! String are immutables. Its methods return always a new copy
End of explanation
"""


print "spam, eggs, foo".split(", ")
print "spam, eggs, foo".split(", ", 1)     # Split by given character, returning a list (optionally specify times to split)

print ", ".join(("spam", "eggs", "foo"))   # Use string as separator to concatenate an iterable of strings

"""
Explanation: NOTE:
The repr module provides a means for producing object representations with limits on the size of the resulting strings. This is used in the Python debugger and may be useful in other contexts as well.
str Return a string containing a nicely printable representation of an object. For strings, this returns the string itself. The difference with repr(object) is that str(object) does not always attempt to return a string that is acceptable to eval(); its goal is to return a printable string. If no argument is given, returns the empty string, ''.
End of explanation
"""


print "%s %s %d" % (spam, spam, 7)         # This is the old string formatting, similar to C

print "{0} {0} {1}".format(spam, 7)        # This is the new string formatting method, standard in Py3k

print "{} {}".format(spam, 7.12345)

print "[{0:16}|{1:16}]".format(-7.12345, 7.12345)  # Use colon and width of formatted value

print "[{0:>16}|{1:<16}]".format(-7.12345, 7.12345)  # Use <, >, =, ^ to specify the alignment of the value

print "[{0:^16.3f}|{1:^16.3f}]".format(-7.12345, 7.12345)  # For floats, use the dot . and the f to specify precission of floats

print "[{0:_^16.3f}|{1:_^16.3f}]".format(-7.12345, 7.12345)  # Specify the filling value before the alignment

print "[{0:^+16.3f}|{1:^+16.3f}]".format(-7.12345, 7.12345)  # Force the sign appearance

print "{0:b} {0:c} {0:o} {0:x}".format(65)  # For integers, specify base representation (binary, unicode character, octal, hexadecimal

"""
Explanation: Let's format strings
End of explanation
"""


# use every cell to run and make the assert pass
# Exercise: write the code 
def minimum(a, b):
    """Computes minimum of given 2 numbers.
    
        >>> minimum(2, 3)
        2
        >>> minimum(8, 5)
        5
        """
    # your code here
    
assert minimum(2,3) == 2

def istrcmp(s1, s2):
    """Compare given two strings for equality, ignoring the case.
    
    	>>> istrcmp("python", "Python")
        True
    	>>> istrcmp("latex", "LaTeX")
        True
    	>>> istrcmp("foo", "Bar")
        False
    """
    # your code here

assert istrcmp("HoLa", "hola") == True

def reverse_text_by_word(text):
    '''given a text, reverse it by words

        >>> reverse_text_by_word('Sparse is better than dense.')
        'dense. than better is Sparse'
    '''
    # your code here

assert reverse_text_by_word('Sparse is better than dense.') == 'dense. than better is Sparse'
    

def sum_chars_text(text):
    '''given a text str, add all chars by its code
        tip:
            >>> c = 'c'
            >>> ord(c)
            99
    '''
    # your code here

assert sum_chars_text("Sume de caracteres") == 1728

"""
Explanation: SOURCES:

http://docs.python.org/2/library/stdtypes.html#numeric-types-int-float-long-complex
http://docs.python.org/2/reference/lexical_analysis.html#strings
http://docs.python.org/2/reference/lexical_analysis.html#encodings
http://docs.python.org/2/library/stdtypes.html#string-methods
http://docs.python.org/2/library/string.html#formatstrings

TIME TO START WORKING
End of explanation
"""


