=============== Python: Numbers =============== There are four distinct numeric types: - ``int``: integers. (Limited precision.) - ``long``: long integers. (Unlimited precision.) They behave exactly like plain ``int``'s, but they can assume arbitrary values. - ``float``: floating point numbers. Also called floats, they represent real numbers. They are written with a decimal point dividing the integer and fractional parts. Floats may also be in scientific notation, with E or e indicating the power of 10. - ``bool``: Boolean conditions. They can assume only two values: ``True`` and ``False``. They are used to represent the result of comparisons. **Example**. Let's create four variables, one for each type, and print them on the screen with ``print``:: x = 10 y = 10L z = 3.14 c = False # Print the four variables print x, y, z, c # The same, adding some text print "x =", x, "y =", y, "z =", z, "; the condition is", c This syntax of ``print`` is valid for all variable types, not only numeric types. Operations ---------- All numeric types support default **arithmetic** operations: - sum ``+``, difference ``-``, product ``*`` - division ``/``, integer division ``//``, remainder ``%``. - power ``**``. The type of the result of ``n operation m`` is the most "complex" type between the type of ``n`` and ``m``. The complexity hierarchy is:: bool < int < long < float **Example**. Two examples of automatic conversion:: result = 1 * 1L # int * long print result print type(result) # long result = 1.0 + 1L # float * long print result print type(result) # float .. warning:: To avoid errors, you should choose the most appropriate type for your variables, so that the *type* of the result is sufficiently "complex" to represent the *value* of the result! See for example the following GC-content exercise. All numeric types support **comparison** operations: - equal ``==`` not equal ``!=`` (or ``<>``) - strictly less than ``<`` strictly greater than ``>`` - less than or equal``<=`` greater than or equal ``>=`` The expression has value ``True`` if the condition is satisfied, otherwise ``False``. The result of a comparison is always ``bool``. **Example**. Let's consider:: na, nc, ng, nt = 2, 6, 50, 4 result = (na + nt) > (nc + ng) print result print type(result) We can build complex conditions using Boolean operations: - ``a and b`` is ``True`` if both ``a`` and ``b`` are ``True``. - ``a or b`` is ``True`` if at least one between ``a`` and ``b`` is ``True``. - ``not a`` is ``True`` only if ``a`` is ``False``. .. warning:: In this context, both ``a`` and ``b`` should be ``bool``, otherwise the result may seem apparently bizarre. **Example**. ``x > 12`` and ``x < 34`` both result ``bool``, so we can combine them to obtain:: # int int # | | print (x > 12) and (x < 34) # \______/ \______/ # bool bool # \___________________/ # bool or:: # int int # | | print (not (x > 12)) or (x < 34) # \______/ # bool # \____________/ \______/ # bool bool # \________________________/ # bool Examples -------- **Example**. Let's calculate the zeros of the quadratic equation :math:`x^2 - 1 = 0`:: a, b, c = 1.0, 0.0, -1.0 delta = b**2 - 4*a*c zero1 = (-b + delta**0.5) / (2 * a) zero2 = (-b - delta**0.5) / (2 * a) print zero1, zero2 Here we use ``x**0.5`` to calculate the square root: :math:`\sqrt{x} = x^\frac{1}{2}`. **Example**. We want to calculate the `GC-content `_ of a genomic region. We know that the region: - Is 1521 nucleotides long. - Contains 316 cytosines. - Contains 235 guanines. The GC-content is defined as :math:`(g + c) / n`. To calculate the result, we may write:: n, c, g = 1521, 316, 235 gc_content = (c + g) / n print gc_content unfortunately, the result of this code is ``0``! Why? The problem is that the resulting proportion, amounting to approximately ``0.362``, cannot be expressed by an integer: we need a rational number. Since both ``n`` and ``m`` are integers, also ``gc_content = n / m`` will be an integer:: print type(gc_content) As a consequence, ``0.362`` is approximated to the nearest integer: ``0``. *Oops*! To solve this problem, ``gc_content`` needs to be a ``float``. We can do it in two ways: - Modifying the type of ``n``, ``m`` or ``g``:: n, c, g = 1521.0, 316.0, 235.0 gc_content = (c + g) / n print gc_content - Using an explicit conversion to a ``float``:: n, c, g = 1521, 316, 235 gc_content = float(c + g) / float(n) print gc_content **Example**. To check that ``x`` falls in the interval A :math:`= [10,50]` let's write:: x = 17 min_a, max_a = 10, 50 inside_a = (min_a <= x <= max_a) print inside_a or:: inside_a = ((x >= min_a) and (x <= max_a)) Assuming that ``inside_a``, ``inside_b`` and ``inside_c`` indicate that ``x`` is contained in interval A, B or C, respectively, we can create more complex conditions:: # x is in at least one interval inside_at_least_one = inside_a or inside_b or inside_c # x is in both A and B, but not in C inside_a_and_b_but_not_c = inside_a and inside_b and (not inside_c) Exercises --------- #. Create the following variables, checking that value and type are correct (using ``print`` and ``type``): #. ``a`` and ``b`` with values ``12`` and ``23`` as integers. #. ``c`` and ``d`` with values ``34`` and ``45`` as long integers. #. ``x`` and ``y`` with values ``21`` and ``14`` as floats. #. Using ``print`` (once), print: #. All the above variables in the same line. #. All the above variables, separated by ``;``, on the same line. #. The text "the product of ``a`` and ``b`` is ``a * b``", replacing ``a``, ``b`` and ``a * b`` with the variable values. #. Find the value and the type of: #. The product of ``a`` and ``b``. #. The difference between ``c`` and ``d``. #. The division of ``x`` by ``y``. #. The integer division of ``a`` by ``b``. #. The integer division of ``c`` by ``d``. #. The integer division of ``x`` by ``y``. #. The product of ``a`` and ``c``. #. The product of ``b`` and ``y``. #. The product of ``x`` and ``d``. #. ``2`` to the power ``0``. #. ``2`` to the power ``100``. #. ``2`` to the power ``1.2``. #. ``2`` to the power ``-2``. #. The square root of ``4``. #. The square root of ``2``. #. What is the difference between: #. ``10 / 12`` #. ``10 / 12.0`` #. ``10 // 12`` #. ``10 // 12.0`` #. What is the difference between: #. ``10 % 3`` #. ``10 % 3.0`` #. Using ``pi = 3.141592`` and given ``r = 2.5``, calculate: #. The circumference of a circle with radius ``r``: :math:`2 \pi r`. #. The area of a circle with radius ``r``: :math:`\pi r^2`. #. The volume of a sphere with radius ``r``: :math:`\frac{4}{3} \pi r^3`. #. Create 2 variables ``a = 100`` and ``b = True``. Using an adequate number of auxiliary variables (with arbitrary names!), give the value of ``a`` to ``b`` and viceversa. (Writing ``a = True`` and ``b = 100`` is not sufficient!) Can it be done with only one auxiliary variable? #. On the same strand of DNA there are 2 genes. The first includes i nucelotides from position 10 to position 20, the second nucleotides from position 30 to position 40. Let's write this:: gene1_start, gene1_end = 10, 20 gene2_start, gene2_end = 30, 40 Given a variable ``pos`` representing an arbitrary position on the DNA strand, write some comparisons to verify if: #. ``pos`` is in the first gene. #. ``pos`` is in the second gene. #. ``pos`` is between the start of the first gene and the end of the second. #. ``pos`` is between the start of the first gene and the end of the second, but not in any of the genes. #. ``pos`` is before the start of the first gene or after the end of the second. #. ``pos`` is inside one of the genes. #. ``pos`` is distant no more than 10 nucleotides from the beginning of the first gene. #. Given three Boolean variables ``t``, ``u``, and ``v``, write expressions that are ``True`` if and only if: #. ``t``, ``u``, ``v`` are all true. #. ``t`` is true or ``u`` is true, but not both. #. Exactly one of the three variables is false. #. Exactly one of the three variables is true. #. Exercise 1.4 from [book2]_: Exponential Growth Given optimal growth conditions, a single E. coli bacterium can divide within 20 minutes. If the conditions stay optimal, how many bacteria are there after 8 hours?