In [1]:
from IPython.display import Image

Práctica Alan - Clase del 23/03/2018

Ejercicio 2.7

Escribir un programa que imprima por pantalla todas las fichas de dominó, de una por línea y sin repetir.


In [2]:
def imprimir_fichas_domino():
    ''' Imprime las fichas del dominó. '''
    for i in range(7):
        for j in range(i,7):
            print(i,"/",j,end=" | ")
        print()
        
def main():
    imprimir_fichas_domino()

main()


0 / 0 | 0 / 1 | 0 / 2 | 0 / 3 | 0 / 4 | 0 / 5 | 0 / 6 | 
1 / 1 | 1 / 2 | 1 / 3 | 1 / 4 | 1 / 5 | 1 / 6 | 
2 / 2 | 2 / 3 | 2 / 4 | 2 / 5 | 2 / 6 | 
3 / 3 | 3 / 4 | 3 / 5 | 3 / 6 | 
4 / 4 | 4 / 5 | 4 / 6 | 
5 / 5 | 5 / 6 | 
6 / 6 | 

Ejercicio 2.8

Modificar el programa anterior para que pueda generar fichas de un juego que puede tener números de 0 a n.


In [3]:
def imprimir_fichas_domino(n=6):
    ''' Imprime las fichas de un juego de dominó con números entre el 0 y n. '''
    for i in range(n+1):
        for j in range(i,n+1):
            print(i,"/",j,end=" | ")
        print()
        
def main():
    imprimir_fichas_domino(8)

main()


0 / 0 | 0 / 1 | 0 / 2 | 0 / 3 | 0 / 4 | 0 / 5 | 0 / 6 | 0 / 7 | 0 / 8 | 
1 / 1 | 1 / 2 | 1 / 3 | 1 / 4 | 1 / 5 | 1 / 6 | 1 / 7 | 1 / 8 | 
2 / 2 | 2 / 3 | 2 / 4 | 2 / 5 | 2 / 6 | 2 / 7 | 2 / 8 | 
3 / 3 | 3 / 4 | 3 / 5 | 3 / 6 | 3 / 7 | 3 / 8 | 
4 / 4 | 4 / 5 | 4 / 6 | 4 / 7 | 4 / 8 | 
5 / 5 | 5 / 6 | 5 / 7 | 5 / 8 | 
6 / 6 | 6 / 7 | 6 / 8 | 
7 / 7 | 7 / 8 | 
8 / 8 | 

Notas de la clase:

  • El parámetro n = 6 es un parámetro "por defecto" y nos da la libertad de pasarle o no el parámetro a la función. Si el parámetro no se indica, entonces la función hace de cuenta que se le pasó el valor por defecto.

Ejercicio 3.3

Escribir una función que, dados cuatro números, devuelva el mayor producto de dos de ellos. Por ejemplo, si recibe los números 1, 5, -2, -4 debe devolver 8, que es el producto más grande que se puede obtener entre ellos (8 = −2 × −4).


In [4]:
def obtener_producto_maximo(a, b, c, d):
    '''
    Dados cuatro números enteros a, b, c y d, devuelve el producto
    máximo entre dos de ellos.
    '''
    # Versión con acumulador
    maximo=max(a*b,a*c)
    maximo=max(maximo,a*d)
    maximo=max(maximo,b*c)
    maximo=max(maximo,b*d)
    maximo=max(maximo,c*d)
    
    return maximo

def obtener_producto_maximo_pythonic(a, b, c, d):
    # Versión python
    return max(a*b, a*c, a*d, b*c, b*d, c*d)

print( "Obtener producto maximo version multilang:", obtener_producto_maximo(2, 3, 4, -1) )
print( "Obtener producto maximo version Python:", obtener_producto_maximo_pythonic(2, 3, 4, -1) )


Obtener producto maximo version multilang: 12
Obtener producto maximo version Python: 12

Notas de la clase:

  • En la mayoría de los lenguajes la función max sólo admite dos parámetros.
  • En Python la función max puede permitir más de dos parámetros con lo cual se puede resolver con una sola llamada a max.

Notas adicionales (Razonamiento de la clase)

Para pensar este ejercicio, hay que primero notar que nadie internamente hace el maximo de todos contra todos, sino, eventualmente de a pares:


In [5]:
Image(filename='./clase-23-03-2018_image/max_pairs.jpg')


Out[5]:

Aunque la forma mas razonable, es no estar guardando muchos resultados intermedios cuando los podemos descartar porque ya sabemos que no sirven:


In [6]:
Image(filename='./clase-23-03-2018_image/max_univalue.jpg')


Out[6]:

Notar que en ambos casos se hace el mismo numero de comparaciones, pero para codificar uno u otro se requieren distinto numero de variables. Mas aun, el segundo modo, permite generalizarlo facilmente para poder utilizarlo dentro de un ciclo, como se hace en un ejercicio mas adelante.

Ejercicio 4.3

Escribir una función que reciba por parámetro una dimensión n, e imprima la matriz identidad correspondiente a esa dimensión.


In [7]:
def imprimir_matriz_identidad(n):
    '''
    Imprime por pantalla una matriz identidad de NxN.
    '''
    for i in range(n):
        for j in range(n):
            if i == j:
                print('1', end=' ')
            else:
                print('0', end=' ')
        print()

imprimir_matriz_identidad(3)


1 0 0 
0 1 0 
0 0 1 

Ejercicio 4.1.a

Escribir una función que dado un número entero n devuelva si es par o no.


In [8]:
def es_par(n):
    '''
    Devuelve True si el número n es par.
    '''
    return (n % 2 == 0)

print('¿Es par 19?', es_par(19))
print('¿Es par 12?', es_par(12))


¿Es par 19? False
¿Es par 12? True

Notas de la clase:

  • No es necesario utilizar un if cuando se va a devolver el valor booleano resultante. La expresión (n % 2 == 0) ya da como resultado un valor de verdad, por lo tanto podemos devolverlo directamente.

Ejercicio 4.1.b

Escribir una función que dado un número entero n devuelva si es primo o no.


In [9]:
def es_primo(n):
    '''
    Devuelve True si el número n es primo.
    '''
    
    # Versión con acumulador
    _es_primo = True
    for m in range(2,n):
       _es_primo = _es_primo and (n%m != 0) 
    return _es_primo

def es_primo2(n):
    '''
    Devuelve True si el número n es primo.
    '''
    
    # Versión sin acumulador
    for m in range(2,n):
        if n % m == 0:
            return False
    return True

print('¿Es primo 27?:', es_primo(27))
print('¿Es primo 31?:', es_primo(31))


¿Es primo 27?: False
¿Es primo 31?: True

Notas de la clase:

  • A diferencia del caso anterior, acá no podemos devolver directamente la condición. Esto se debe a que uno de los valores de verdad nos indica el fin de la función pero el otro no. Es decir, si n % m es 0, estamos en condiciones de afirmar que el número no es primo y por lo tanto podemos devolver False directamente. Pero si n % m es distinto de 0, entonces todavia no sabemos nada y tenemos que seguir iterando.

In [10]:
Image(filename='./clase-23-03-2018_image/and_univalue.jpg')


Out[10]:

Un error muy común es intentar devolver la condición adentro de ciclos. En general, adentro de un ciclo no debería devolverse una condición directamente.

Material adicional

Les recomendamos que para que quede todo claro, prueben al menos los ejercicios 3.3 y 4.1.b en Python Tutor, ademas les va a servir para repasar la parte de seguimientos. Les dejamos de ejemplo una ejecucion para la version con acumulador del 4.1.b, y que vean que efectivamente se cumple lo que se muestra en el diagrama.