Python Programming (very fast) Introduction#

Importing modules#

Python has an extensive standard library (https://docs.python.org/3/library/) to perform several task in optimized and easy-to-use way. For basic mathematical operations you can just use the normal operators, but for other standard functions, like sin, you could import the standard math module, or , much better, use either numpy or scipy modules

import math as m # imports the math module with an alias m
# import math # imports math module but you need to use math.sin or math.cos
# from math import * # DO NOT do this: exposes all inners from math

x = 5.2
y = m.sin(x)
print(x, y)
Exercise: Copy and execute the previous code in the following cell (use shift+enter to execute)
### BEGIN SOLUTION
import math as m # imports the math module with an alias m
# import math # imports math module but you need to use math.sin or math.cos
# from math import * # DO NOT do this: exposes all inners from math

x = 5.2
y = m.sin(x)
print(x, y)
### END SOLUTION
5.2 -0.8834546557201531
Exercise: Now replace math by numpy and execute it. Is there any difference?
### BEGIN SOLUTION
import numpy as np 

x = 5.2
y = np.sin(x)
print(x, y)
### END SOLUTION
5.2 -0.8834546557201531

Looking for help#

What are the units of the argument for the sin function? Are there any other functions provided by the numpy module? Check the documentation using either google or, inside a notebook

help(np.sin)
help(np)
np.sin?
import numpy as np
help(np.sin)
Help on ufunc in module numpy:

sin = <ufunc 'sin'>
    sin(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])
    
    Trigonometric sine, element-wise.
    
    Parameters
    ----------
    x : array_like
        Angle, in radians (:math:`2 \pi` rad equals 360 degrees).
    out : ndarray, None, or tuple of ndarray and None, optional
        A location into which the result is stored. If provided, it must have
        a shape that the inputs broadcast to. If not provided or None,
        a freshly-allocated array is returned. A tuple (possible only as a
        keyword argument) must have length equal to the number of outputs.
    where : array_like, optional
        This condition is broadcast over the input. At locations where the
        condition is True, the `out` array will be set to the ufunc result.
        Elsewhere, the `out` array will retain its original value.
        Note that if an uninitialized `out` array is created via the default
        ``out=None``, locations within it where the condition is False will
        remain uninitialized.
    **kwargs
        For other keyword-only arguments, see the
        :ref:`ufunc docs <ufuncs.kwargs>`.
    
    Returns
    -------
    y : array_like
        The sine of each element of x.
        This is a scalar if `x` is a scalar.
    
    See Also
    --------
    arcsin, sinh, cos
    
    Notes
    -----
    The sine is one of the fundamental functions of trigonometry (the
    mathematical study of triangles).  Consider a circle of radius 1
    centered on the origin.  A ray comes in from the :math:`+x` axis, makes
    an angle at the origin (measured counter-clockwise from that axis), and
    departs from the origin.  The :math:`y` coordinate of the outgoing
    ray's intersection with the unit circle is the sine of that angle.  It
    ranges from -1 for :math:`x=3\pi / 2` to +1 for :math:`\pi / 2.`  The
    function has zeroes where the angle is a multiple of :math:`\pi`.
    Sines of angles between :math:`\pi` and :math:`2\pi` are negative.
    The numerous properties of the sine and related functions are included
    in any standard trigonometry text.
    
    Examples
    --------
    >>> import numpy as np
    
    Print sine of one angle:
    
    >>> np.sin(np.pi/2.)
    1.0
    
    Print sines of an array of angles given in degrees:
    
    >>> np.sin(np.array((0., 30., 45., 60., 90.)) * np.pi / 180. )
    array([ 0.        ,  0.5       ,  0.70710678,  0.8660254 ,  1.        ])
    
    Plot the sine function:
    
    >>> import matplotlib.pylab as plt
    >>> x = np.linspace(-np.pi, np.pi, 201)
    >>> plt.plot(x, np.sin(x))
    >>> plt.xlabel('Angle [rad]')
    >>> plt.ylabel('sin(x)')
    >>> plt.axis('tight')
    >>> plt.show()

Printing and reading to and from the screen#

You have already seen how to print to the screen. To read, you can use the function call input. Try it:

var = input("Please write something :\t")
print("You have written : " + var)
print(f"You have written : {var}") # uses a f-string: https://realpython.com/python-f-strings/
---------------------------------------------------------------------------
StdinNotImplementedError                  Traceback (most recent call last)
Cell In[4], line 1
----> 1 var = input("Please write something :\t")
      2 print("You have written : " + var)
      3 print(f"You have written : {var}") # uses a f-string: https://realpython.com/python-f-strings/

File /opt/hostedtoolcache/Python/3.11.13/x64/lib/python3.11/site-packages/ipykernel/kernelbase.py:1274, in Kernel.raw_input(self, prompt)
   1272 if not self._allow_stdin:
   1273     msg = "raw_input was called, but this frontend does not support input requests."
-> 1274     raise StdinNotImplementedError(msg)
   1275 return self._input_request(
   1276     str(prompt),
   1277     self._parent_ident["shell"],
   1278     self.get_parent("shell"),
   1279     password=False,
   1280 )

StdinNotImplementedError: raw_input was called, but this frontend does not support input requests.

You can also format the printing string, like you have done in c/c++ . For example, you can write something like

x = 5
y = 2.34
print("x = %04d \t y = %.1f \n y=%20.16e\n"%(x, y, y))
print(f"x = {x:04d} \t y = {y:.1f} \n y={y:20.16e}")
x = 0005 	 y = 2.3 
 y=2.3399999999999999e+00

x = 0005 	 y = 2.3 
 y=2.3399999999999999e+00

Note: if you need to manipulate strings and numbers, you should cast the number to string by using str, as in str(x) .

Exercise: Print the sum of two numbers with 5 decimals, filled with 0, and in field of 10 spaces
x = 32.6
y = -4.7
### BEGIN SOLUTION
print(f"{x+y:010.5f}")
### END SOLUTION
0027.90000

Selection structures : if, if else#

This is a simple example on how to use if to select from several options

m = 5
if m < 1:
    print (f"{m} is smaller than 1")
elif 1 <= m <= 4:
    print (f"{m} is in between 1 and 4")
else :
    print (f"{m} is larger than 4")
5 is larger than 4

You can also compare values directly, or even compare several values

print(2 == 3)
print(2 == 2 and 3 > 9)
print([2, 3] == [3, 2])
print([2, 3] == [2, 2])
print([2, 3] == [2, 3])
False
False
False
False
True
Exercise: Read a number and indicate if the number is even or odd
### BEGIN SOLUTION
num = int(input())
if (num%2 == 0):
    print(f"{num} is even")
else:
    print(f"{num} is odd")
### END SOLUTION
10939384
10939384 is even

Loop structures: for and while#

N = 5
i = 0
while i < N:
    print (i, end=" ")
    i = i+1
0 1 2 3 4 
for ii in range(1, 10):
    print(f"{ii}", end=" ")
1 2 3 4 5 6 7 8 9 
name = "My name" # a string is an array for characters
for c in name:
    print (c, end="-")
print()
print(name[0])
print(name[-1])
M-y- -n-a-m-e-
M
e
Exercise: Print values from 0.0, to 1.0 (exclusive), in steps of 0.05
# ii = 0.0
# while ii < 1.0:
#     print(ii)
#     ii = ii + 0.05
### BEGIN SOLUTION
xmin = 0.0
xmax = 1.0
dx = 0.05
N = int((xmax - xmin)/dx)
for ii in range(0, N):
    print(f"{xmin + ii*dx}")
### END SOLUTION
0.0
0.05
0.1
0.15000000000000002
0.2
0.25
0.30000000000000004
0.35000000000000003
0.4
0.45
0.5
0.55
0.6000000000000001
0.65
0.7000000000000001
0.75
0.8
0.8500000000000001
0.9
0.9500000000000001
Exercise: Now use numpy to do the same (check for the linspace function)
### BEGIN SOLUTION
# numpy solution
import numpy as np
print(np.linspace(0.0, 1.0, 20, endpoint=False))
### END SOLUTION
[0.   0.05 0.1  0.15 0.2  0.25 0.3  0.35 0.4  0.45 0.5  0.55 0.6  0.65
 0.7  0.75 0.8  0.85 0.9  0.95]

How to declare functions#

Functions are the next construct necessary for the a good program design. A function should be defined by using the keyword def .

def my_function() : 
    print ("I am the function")
    
my_function() # this calls the function    
I am the function
# this shows how to pass arguments
def my_function(x):
    print (f"Value of argument is {x}")
    
#my_function() # error, requires argument
my_function(-3)
my_function(0.9)
Value of argument is -3
Value of argument is 0.9
# this shows how to pass arguments, and assign default values
def my_function(x = 0):
    print (f"Value of argument is {x}")
    
my_function() # no longer an error
my_function(-3)
Value of argument is 0
Value of argument is -3
# this shows how to pass arguments, assign default values, and also calls by named arguments
def my_function(x = 0, y = 1):
    print ("Calling my_function")
    print ("x " + str(x))
    print ("y " + str(y))
    
my_function() # no longer an error
my_function(-3, 2) # x = -3, y = -2
my_function(y=-3, x=2) # x = 2, y = -3
Calling my_function
x 0
y 1
Calling my_function
x -3
y 2
Calling my_function
x 2
y -3

Exercises#

Convert from Farenheit to Celcius#

Write a function that receives a temperature in F and prints it in C

def FtoC(f):
### BEGIN SOLUTION
    return f"The temperature {f} F is equivalent to {(f-32)*5.0/9.0:4.2f} C"
### END SOLUTION
assert FtoC(0) == "The temperature 0 F is equivalent to -17.78 C"
assert FtoC(10.3) == "The temperature 10.3 F is equivalent to -12.06 C"
### BEGIN HIDDEN TESTS
assert FtoC(-10.3) == "The temperature -10.3 F is equivalent to -23.50 C"
### END HIDDEN TESTS

Triangle vertexes#

The coordinates for the vertexes of a given triangle are written into a file in the form \begin{align*}x_1\ \ \ y_1\x_2\ \ \ y_2\x_3\ \ \ y_3 \end{align*} Write a program that reads this values, and computes the area of the triangle, defined as $\( A = \frac{1}{2}[x_2y_3 - x_3y_2 - x_1y_3 + x_3y_1 + x_1y_2 - x_2y_1]\)$. Use functions.

RC circuit#

Write a Python program that uses a loop to simulate the behavior of an RC circuit. The program should ask the user for the resistance and capacitance values of the circuit and should calculate the voltage across the capacitor as a function of time. The program should then create a plot of the voltage across the capacitor versus time.

Spring system#

Write a Python program that uses a loop to simulate the motion of a mass-spring system. The program should ask the user for the mass of the object, the spring constant, and the initial displacement from equilibrium. The program should then calculate the position of the object as a function of time and create a plot of the position versus time.

Projectile#

Write a Python program that uses a loop to simulate the motion of a projectile under the influence of gravity. The program should ask the user for the initial velocity and launch angle of the projectile, and should calculate the trajectory of the projectile over time. The program should then create a plot of the trajectory of the projectile. Use the Euler integration algorithm to compute the next position and velocity. Compare adding a damping linear force with air.

Random numbers#

Write a Python program that reads three integers N, lower, upper, and generates a list of N random integers between lower and upper, inclusive. The program should then print out the number of integers in the list that are even and the number of integers that are odd. Finally, the program should create a bar chart that shows the number of even and odd integers in the list. Then create 4 plots with increasing N showing that limit distribution of even and odd numbers.

Heatmap#

Write a Python function that takes an integer n as input and returns a NumPy array of size n x n, where the elements of the array are random integers between lower and upper, which are also arguments of the function. Write a second function that takes the NumPy array as input and creates a heatmap of the array. Use these functions to create a program that generates a mxm NumPy array of random integers and displays it as a heatmap. Use several m

Fitting with scipy#

Here we will learn how to perform a non-linear fit. To do so, we will generate some random data and then fit it. First, create a function that represents the theoretical trend that you want to fit. Now create two numpy arrays, xdata and ydata. For xdata use the linspace function on the range you are interested in. For ydata use the theoretical function and add a gaussian noise for each point. Now use the scipy.curve_fit function to fit the data, and print the fit parameters and their errors. Plot both the data and the fit.