CentraleSupélec LMF, UMR CNRS 9021
Département informatique Laboratoire Méthodes Formelles
Bât Breguet, 3 rue Joliot-Curie Bât 650 Ada Lovelace, Université Paris Sud
91190 Gif-sur-Yvette, France Rue Noetzlin, 91190 Gif-sur-Yvette, France
TD n°10 SIP

Le sujet SIP-TD10.pdf

Un sketch (attention humour geek anglais) de Matt Parker sur les écrans et les feuilles de calcul Excel : https://www.youtube.com/watch?v=UBX2QQHlQ_I

Éléments de corrigé

from matplotlib import pyplot as plt
import numpy as np

def gender_city_happiness():
    city=['Delhi','Beijing','Washington','Tokyo','Moscow']
    Gender=['Male','Female']
    pos = np.arange(len(city))
    bar_width = 0.35
    Happiness_Index_Male=[60,40,70,65,85]
    Happiness_Index_Female=[30,60,70,55,75]
    plt.bar(pos, Happiness_Index_Male, bar_width, color='blue', edgecolor='black')
    plt.bar(pos+bar_width, Happiness_Index_Female, bar_width, color='pink', edgecolor='black')
    plt.xticks(pos+bar_width/2, city)
    plt.xlabel('City', fontsize=16)
    plt.ylabel('Happiness Index', fontsize=16)
    plt.title('Group Barchart - Happiness index across cities By Gender',fontsize=18)
    plt.legend(Gender,loc=2)
    plt.show()

def center_axes(fig):
    ax = plt.figure().add_subplot(1, 1, 1)
    # Move left y-axis and bottom x-axis to centre, passing through (0,0)
    ax.spines['left'].set_position('center')
    ax.spines['bottom'].set_position('center')
    # Eliminate upper and right axes
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    # Show ticks in the left and lower axes only
    ax.xaxis.set_ticks_position('bottom')
    ax.yaxis.set_ticks_position('left')

def plot_parabola():
    x = np.linspace(-2,2,200) # 200 linearly spaced numbers
    y = x**2
    center_axes(plt)
    plt.plot(x,y)
    plt.show()

import math

def plot_sine():
    x = np.linspace(-2, 2, 200)
    y1 = np.sin(math.pi * x)
    y2 = np.sin(2 * math.pi * x)
    center_axes(plt)
    plt.plot(x, y1, x, y2)
    plt.show()

def plot_sine_simp():
    x = [-2+i/50 for i in range(201)]
    y1 = [math.sin(math.pi * i) for i in x]
    y2 = [math.sin(2 * math.pi * i) for i in x]
    center_axes(plt)
    plt.plot(x, y1, x, y2)
    plt.show()

def two_figures():
    x = np.linspace(-2,2,200)
    plt.subplot(211)
    plt.plot(x, np.sin(math.pi * x), 'rv')
    plt.subplot(212)
    plt.plot(x, np.sin(2 * math.pi * x), 'b+')
    plt.show()


# Exercise about Pi

# The red square without using numpy
def red_square(n) :
    img = [[(128,29,59) for i in range(n)] for j in range(n)]
    plt.imshow(img)
    plt.show()

# Other way if pyplot complains about data types
# uint8 = unigned integer coded on 8 bits (0..255)
def red_square_uint(n) :
    img = [[(128,29,59) for i in range(n)] for j in range(n)]
    plt.imshow(np.asanyarray(img, dtype='uint8'))
    plt.show()

def deep_red_square(n):
    img = np.zeros((n, n, 3), dtype='uint8') # you could also use a list of list of list.
    for i in range(n):
        for j in range(n):
            img[i][j] = [128,29,58]
    imgplot = plt.imshow(img)
    plt.axis('off')
    plt.show()

# Question 6
colors = [
    [230, 230, 230],   # white
    [255,  65,  54],   # red
    [255,  53,  27],   # orange
    [255, 220,   0],   # yellow
    [1,   255, 112],   # light green
    [61,  153, 112],   # dark green
    [57,  204, 204],   # light blue
    [0,   116, 217],   # dark blue
    [177,  13, 201],   # purple
    [240,  18, 190]    # pink
]

def color_square_digits(dig, n):
    img=[[[0,0,0] for i in range(n)] for j in range(n)]
    i = 0
    j = 0
    for k in range(len(dig)):
        img[i][j] = colors[int(dig[k])]
        j = (j + 1) % n
        if j == 0:
            i = (i + 1) % n
            if i == 0 :
                break
    plt.imshow(img)
    plt.axis('off')
    plt.show()

def frac(a, b, n) :
    """
    return the n first digits of the fractional part of a/b
    """
    digits = ""
    for d in range(n) :
        a *= 10
        digits += str((a // b) % 10)
    return digits

big_pi = """\
31415926535897932384626433832795028841971693993751058209749445923078164062862\
089986280348253421170679821480865132823066470938446095505822317253594081284811\
174502841027019385211055596446229489549303819644288109756659334461284756482337\
867831652712019091456485669234603486104543266482133936072602491412737245870066\
063155881748815209209628292540917153643678925903600113305305488204665213841469\
519415116094330572703657595919530921861173819326117931051185480744623799627495\
673518857527248912279381830119491298336733624406566430860213949463952247371907\
021798609437027705392171762931767523846748184676694051320005681271452635608277\
857713427577896091736371787214684409012249534301465495853710507922796892589235\
420199561121290219608640344181598136297747713099605187072113499999983729780499\
510597317328160963185950244594553469083026425223082533446850352619311881710100\
031378387528865875332083814206171776691473035982534904287554687311595628638823\
537875937519577818577805321712268066130019278766111959092164201989380952572010\
654858632788659361533818279682303019520353018529689957736225994138912497217752\
834791315155748572424541506959508295331168617278558890750983817546374649393192\
550604009277016711390098488240128583616035637076601047101819429555961989467678\
374494482553797747268471040475346462080466842590694912933136770289891521047521\
620569660240580381501935112533824300355876402474964732639141992726042699227967\
823547816360093417216412199245863150302861829745557067498385054945885869269956\
909272107975093029553211653449872027559602364806654991198818347977535663698074\
265425278625518184175746728909777727938000816470600161452491921732172147723501\
414419735685481613611573525521334757418494684385233239073941433345477624168625\
189835694855620992192221842725502542568876717904946016534668049886272327917860\
857843838279679766814541009538837863609506800642251252051173929848960841284886\
269456042419652850222106611863067442786220391949450471237137869609563643719172\
"""

# color_square_digits(frac(1,17,40*40), 40)
# color_square_digits(big_pi, 40)


# Koch snowflake
import cmath  # complex numbers

def iso_triangle() :
    a = complex(0,0)
    b = complex(1,0)
    ac = (b-a) * cmath.rect(1, math.pi/3)
    c = a + ac
    return ([a.real, c.real, b.real, a.real],
            [a.imag, c.imag, b.imag, a.imag])

# plt.axes().set_aspect('equal')
# isot = iso_triangle()
# plt.plot(isot[0], isot[1])

def koch_seg(segx, segy, pos = 0) :
    # We use complex numbers to represent points
    a = complex(segx[pos], segy[pos])         # get point A
    b = complex(segx[pos + 1], segy[pos + 1]) # and point B
    ab = b - a      # Compute vector AB
    ac = ab / 3     # Cut the segment at 1/3 of its length
    c = a + ac      # to find point C
    # The next point is at 1/3 of AB, turned by 60° (pi/3), relative to C
    cd = ac * cmath.rect(1, math.pi/3)  # Can also be written ac * complex(math.cos(math.pi/3), math.sin(math.pi/3))
    d = c + cd
    # The last point is at 2/3 of AB
    ae = 2 * ab / 3
    e = a + ae
    return ([a.real, c.real, d.real, e.real, b.real],
            [a.imag, c.imag, d.imag, e.imag, b.imag])

def koch_iter(segsx, segsy) :
    finalx = []
    finaly = []
    for pos in range(len(segsx) - 1) :
        nsegs = koch_seg(segsx, segsy, pos)
        finalx = finalx + nsegs[0]
        finaly = finaly + nsegs[1]
    return (finalx, finaly)

def vonKoch(n) :
    k = iso_triangle()
    for i in range(n) :
        k = koch_iter(k[0], k[1])
    plt.axes().set_aspect('equal')
    plt.plot(k[0], k[1])
    plt.show()