jueves, 27 de septiembre de 2018

La leyenda del Ajedrez

Ha todos nos han contado la famosa leyenda del ajedrez, en la que un rey de la India le prometío dar a un savio que inventó el ajedrez cualquier recompensa, el savio le didió un grano de trigo por la primera casilla y que por cada casilla fuera doblando el numero de granos que havía antes. Los matematicos del rey despues de muchos dias de calculos le informaron que ese numero era tan grande que no havía suficiente trigo en el mundo para pagar al savio, esto enseño al rey ha apreciar mas las cosas. Y por ese motivo hemos hecho un codigo en Python para calcular ese numero. Aquí teneis el codigo:

 i=0  
 s=0  
 while i<64:  
  s+=2**i  
  print(i+1,2**i,s)  
  i+=1  
 print('Unos',int(round(s/25000000000000,0)),'millones de toneladas')  
 print('En 2018, la producción mundial fue de 750 millones de toneladas')  

Eso ultimo lo he añadido por dar una mejor perspectiva al pedazo de numero que tenemos delante.

miércoles, 26 de septiembre de 2018

Histograma en Python

Para hacer un histograma en Python vamos ha utilizar la librería matplotlib y generaremos los valores de manera aleatoria. El código es este:

import matplotlib.pyplot as plt
import random as ran
values=[]
for x in range(1,11):
   values.append(ran.randrange(11))
plt.hist(values, bins=10)
plt.show()
Usando el for vamos a ir generando números aleatorios y metiendo los en values.
Aquí entra la parte de la librería matplotlib, le pedimos que ejecute hist para indicar que queremos hacer un histograma, también le damos el valor de values para indicar con valores queremos trabajar y por ultimo indicamos los bins que determina el numero de columnas que queremos que se divida la información. Lo imprimimos todo y ya está.

Una variación que podemos hacer es que sin que tú hagas nada te genere mas de histograma con este codigo:


import matplotlib.pyplot as plt
import random as ran
def histograma():
    values=[]
    for x in range(1,11):
        values.append(ran.randrange(11))
    #values=[0,0.6,1.4,1.6,2.2,2.5,2.6,3.2,3.5,3.9,4.2,6]
    plt.hist(values, bins=10)
    plt.show()

for x in range(1,6):
    histograma()

Nota: En la mayoría de paginas web que ejecutan Python no sé podrán ver los gráficos en sí. Para ello necesitaras usar un programa mas potente que pueda procesar las librerías.
Si ejecutas este código en algunos editores de código como PyCharm, al importar las librerías no solo tendrás que importarla escribiéndola en el código si no que tendrás que importarla desde el propio editor. Aquí os enseñamos cómo hacerlo: https://www.youtube.com/watch?v=aROm4KYHXLI&feature=youtu.be

lunes, 24 de septiembre de 2018

Adivina el número secreto en Python

Reto: Adivina el número secreto

Se genera un número aleatorio entero entre 1 y 100. El usuario debe adivinar el número secreto, diciendo en cada tirada si es mayor o menor.




Método 1

Importamos la librería random para generar el número aleatorio secreto n. Preguntamos al usuario por el primer número. Se añade int antes del input para convertir su respuesta en un número entero, ya que si esto no se hace se capturaría un string. Nos metemos en un bucle de tipo while donde la condición analiza si el número proporcionado por el usuario es distinto del número secreto. Dentro de bucle creamos un condicional if para el caso en que el número sea mayor o bien sea menor que el número secreto. En cada caso informamos al usuario con un mensaje donde se le pide que de otro número. Fuera del bucle tenemos una última línea de código que imprime un mensaje donde se felicita al usuario por haber adivinado el número secreto n.

import random
n=random.randrange(1,100)
nu=int(input('Dime el número que crees que he elegido: '))
while nu!=n:
    if nu>n:
        nu=int(input('El número es mas pequeño'))
    elif nu<n:
        nu=int(input('El número es mas grande'))
print('Felicidades has adivinado que el número secreto es:',n)


Método 2

En este método hemos añadido un contador c para ir anotando las tiradas que se realizan y al final informar al usuario sobre el número de tiradas necesarias hasta que ha adivinado el número secreto.



import random
n=random.randrange(1,100)
nu=int(input('Dime el número que crees que he elegido '))
c=1
while nu!=n:
  c+=1
  if nu>n:
      nu=int(input('El número es mas pequeño'))
  elif nu<n:
      nu=int(input('El número es mas grande'))
print('Felicidades has adivinado que el número secreto es:',n)
print('Y lo has adivinado en',c,'intentos.')

Progresión geométrica en Python

Reto: Progresión geométrica

Calcular cuantos granos de trigo tendríamos que utilizar si por cada casilla de un tablero de ajedrez pusiéramos un grano en la primera casilla, dos en la segunda, cuatro en la tercera, y así doblando hasta la última.



Este es el caso de la leyenda de los granos de trigo y el tablero de ajedrez.


Método 1

La variable s se inicializa en cero, y contendrá la suma de todos los granos de trigo que se van anotando en cada casilla. Nos metemos en un bucle for que usa la variable i que va entre cero y 64, incluido el cero y excluido el 64. Dentro del bucle calculamos el número de granos de la casilla i-ésima elevando al cuadrado, y esto se va acumulando en la variable s que es la suma de todos ellos. Se imprime el cómputo por cada casilla y fuera del bucle imprimimos nuevamente el resultado final en notación científica. Observe que hemos separado en dos líneas impresas usando /n. La notación científica se puede implementar usando la e minúscula o la E mayúscula.

s=0
for i in range(8*8):
  s+=2**i
  print(i+1,2**i,s)
print("En notación científica es %e,\n y el total es: %E granos de trigo." % (2**i,s))


Método 2

En este caso usamos un bucle de tipo while. Al final hacemos una estimación de que en un kilo de trigo hay 25.000 granos y con ella calculamos redondeando cuantos millones de toneladas serían necesarios, comparándolo con la producción mundial.

i=0
s=0
while i<64:
  s+=2**i
  print(i+1,2**i,s)
  i+=1
print('Unos',int(round(s/25000000000000,0)),'millones de toneladas')
print('En 2018, la producción mundial fue de 750 millones de toneladas')

miércoles, 29 de agosto de 2018

Generar y ordenar palabras en Python

Reto: Ordenar palabras

Crear una serie de 10 palabras donde sus letras se obtienen de forma aleatoria. Mostrar estas palabras y mostrar esas mismas palabras ordenadas alfabéticamente.



Método 1

Creamos la lista frase que contendrá diez palabras compuestas cada una de ellas por cuatro letras aleatorias. La variable L contienen todo el abecedario en forma de lista. El primer bucle for contiene diez ciclos para generar las diez palabras. En el segundo bucle for es donde generamos cada palabra recogida como string en la variable p. Para ello, se elige aleatoriamente cada letra de la lista L.
Una vez generada la palabra p está se añade a la lista L con append.


import random
frase=[]
L=list('abcdefghijklmnopqrstuvwxyz')
for i in range(0,11):
  p=''
  for j in range(4):
    p+=L[random.randint(0,25)]
  frase.append(''.join(p))
print(frase)
print(sorted(frase))


Método 2

Con este método vamos a crear palabras donde se alternen parejas de consonante y vocal. La variable n contiene el número de parejas elegidas. Si n es tres obtendremos palabras con seis letras. La variable c es un string que contiene las consonantes y la variable v es otra cadena con las vocales. Inicializamos la variable L como lista vacía. Nos metemos en un primer bucle for de diez ciclos para generar las diez palabras. El segundo bucle for añade aleatoriamente una letra consonante y luego una letra vocal para que formen parejas, y se repite n veces.

import random
n=3 # nº de parejas de letras consonante-vocal
c='bcdfghjklmnpqrstvwxyz'
v='aeiou'
L=[]
for i in range(10):
  palabra=''
  for j in range(n):
    palabra+=''.join(random.choice(c))
    palabra+=''.join(random.choice(v))
  L.append(palabra)
print(L)
print(sorted(L))

viernes, 24 de agosto de 2018

Alternos con excepciones

Reto: Alternos con excepciones

Imprimir diez números aleatorios sin repetición entre 100 y 130, excepto los números 110, 115, 120 y alternando par, impar, comenzando por par.




Método 1

Importamos randint de la librería random. Creamos la lista L inicialmente vacía. Nos metemos en un bucle while con 10 ciclos. Por cada vuelta generamos un número aleatorio par entre 100 y 130. Si el número generado no es 115, ni 120, ni 125, y no está en la lista L, para evitar repeticiones, entonces nos metemos en otro condicional if.
En el segundo condicional se analiza la condición de que el número aleatorio sea par y que el lugar (n) que toca sea par, para garantizar que se trata de la ubicación donde ha de ir un número par, entonces se añade a la lista con append. y el contador n se incrementa en 1. La otra condición del elif analiza si el número aleatorio en impar y toca que la ubicación donde tenga que ir sea también impar, entonces se añade con append y el contador n se incrementa en 1.
Finalmente se imprime la lista y luego se vuelve a imprimir ordenada con sort.

from random import randint
n=0
L=[]
while n<10:
  t=randint(100,131)
  if t not in (115,120,125) and t not in L:
    if t%2==0 and n%2==0: #par y toca par
      L.append(t)
      n+=1
    elif t%2!=0 and n%2!=0: #impar y toca impar
      L.append(t)
      n+=1
print(L)
L.sort()
print(L)


Método 2

Generamos la lista Lp que contendrá ordenados todos los números pares posibles, que son los comprendidos entre 100 y 130 salvo el 110 y el 120.
Generamos la lista Li que contendrá ordenados todos los números impares posibles, que son los comprendidos entre 100 y 130 salvo el 115.
Imprimimos las listas Lp y Li.
Con random.shuffle barajamos cada lista. Creamos la lista L, inicialmente vacía. Nos metemos en un bucle for de 5 ciclos. Aunque nos piden 10 números en este retos el bucle for es de 5 ciclos ya que en cada uno de ellos se genera una pareja de números, el primero par y el segundo impar. Para generar el número par se toma el primer par de la lista de pares Lp, que ya se desordenó anteriormente, y para generar el número impar se hace lo mismo con la lista de impares Li.
El resultado será una lista de números L que contiene 5 parejas de números par, impar, que comienzan por par y se van alternando.

import random
Lp=[i for i in range(100,131,2) if i not in (110,120)] #genera todos los pares posibles
Li=[i for i in range(101,131,2) if i!=115]             #genera todos los impares posibles
print(Lp)
print(Li)
random.shuffle(Lp) #baraja los pares
random.shuffle(Li) #baraja los impares
L=[]
for k in range(5): # son 5 parejas de par, impar.
  L.append(Lp[k])  # toma el pare de indice k
  L.append(Li[k])  # toma el impar de indice k
print(L)

domingo, 19 de agosto de 2018

Aleatorios con excepciones

Reto: Aleatorios con excepciones

Generar números aleatorios pares entre 100 y 130, salvo 110 y 120.

Veamos varios casos, que pueden ser:

  • con repetición
  • sin repetición




Método 1

Importamos la librería random. Creamos la lista L inicialmente vacía. Nos metemos en un bucle for con 16 ciclos. Por cada vuelta generamos un número aleatorio par entre 100 y 130. Si el número generado no es 110, ni 120, entonces se añade a la lista con append.
Finalmente se imprime la lista y luego se vuelve a imprimir ordenada con sorted.

import random
L = []
for i in range(16):
    x = random.randrange(100,131,2)
    if x not in (110,120):
        L.append(x)
print(L)
print(sorted(L))


Método 2

Este método realiza un tratamiento similar al anterior pero usa List Comprehensions para comprimir el código en una sola línea.

import random
L=[r for r in [random.randint(100,130) for s in range(30)] if r%2==0 and r not in (110,120)]
print(L)
print(sorted(L))


Método 3

En este caso no importamos la librería random completa, únicamente importamos el método randint que genera números aleatorios entre 50 y 65. Con un if eliminamos aquellos valores que sean 55 o 60. El valor de la variable i que supere el filtro se multiplica por 2 para obtener los pares entre 100 y 130, excluidos del tratamiento los valores 110 y 120.

from random import randint
L = [i*2 for i in [randint(50,65) for j in range(16)] if i not in (55,60)]
print(L)
print(sorted(L))


Método 4

Este método es similar al método anterior si bien no es necesario multiplicar i por dos ya que los valores generados exigimos que sean pares incluyéndolo como una condición adicional en el if.

import random
L = [i for i in [random.randint(100,130) for j in range(30)] if i not in (110,120) and i%2==0]
print(L)
print(sorted(L, reverse=True))


Método 5

Usamos rando.sample que nos permite elegir una muestra aleatoria entre los valores generados. En este caso los valores obtenidos serán sin repetición gracias a que este método está diseñado para elegir sin repetición de una secuencia de números.

import random
L=[i for i in random.sample(range(100,131,2),16) if i not in (110,120)]
print(L)
L.sort(reverse=True)
print(L)


Método 6

Usamos random.shuffle sobre la lista generada previamente. Este método devuelve una nueva lista mezclada, lo que permite obtener un resultado sin repetición.

import random
L=[i for i in range(100,131,2) if i!=110 and i!=120]
random.shuffle(L) #desordena la lista
print(L)
print(sorted(L))

sábado, 18 de agosto de 2018

Donut de colores

 Utilizando la librería matplotlib.pyplot hemos conseguido generar unos puntos de diferentes colores y que no se impriman cuando están dentro de un rango, en este caso hemos creado una forma redonda como si fuera un Donut, aunque se puede cambiar para que haga cualquier forma.

El codigo Python:
from math import sqrt  
import random  
import matplotlib.pyplot as plt  
n = 10000  
p=q=0  
plt.figure(figsize=(7,7))  
for i in range(n):  
  p = random.random() * 8 - 4  
  q = random.random() * 8 - 4  
  r = sqrt(p ** 2 + q ** 2)  
  if 2<r<4:  
    x,y=p,q  
    plt.plot(x,y,'o',markersize=1)  
plt.show()  

El resultado de ese codigo:

En el código utilizamos coordenadas cartesianas para saber en qué lugar van a estar los puntos, generamos aleatoriamente las variables x e y que pondrá los puntos aleatoriamente por toda la pantalla, no sin antes usando un if para filtrar los puntos que son impresos en la pantalla, aquí es donde podemos elegir la forma de la figura que se termine de imprimir en pantalla.

En nuestro caso esto es la parte que crea esa forma de donut.

p = random.random() * 8 - 4   
q = random.random() * 8 - 4   
r = sqrt(p ** 2 + q ** 2)   
if 2<r<4:   
  x,y=p,q   
  plt.plot(x,y,'o',markersize=1)   

Primero generamos p y q aleatoriamente con random.random(), como esto solo genera números entre uno y cero la multiplicarlo por ocho y restarle cuatro le damos los márgenes que queremos para las coordenadas cartesianas. Luego aplicamos el teorema de Pitágoras para saber a qué distancia está ese punto desde el centro del plano.

Esta imagen puede que ayude a entender lo que estamos intentando hacer:


Y luego usando un if, si ese punto está dentro de las coordenadas dos y cuatro entonces les paso los valores de p,q y x,y para añadirlo al plot y luego imprimirlo.

Nota: Si ejecutas este código en algunos editores de código como PyCharm, al importar la librería matplotlib no solo tendrás que importarla escribiéndola en el código si no que tendrás que importarla desde el propio editor. Aquí os enseñamos cómo hacerlo: https://www.youtube.com/watch?v=aROm4KYHXLI&feature=youtu.be

sábado, 4 de agosto de 2018

Generar números aleatorios sin repetición y ordenarlos en Python

Reto: Ordenar números

Imprimir una lista de 10 números aleatorios sin repetición que varíen en el rango 80 a 99. Volver a imprimir la lista pero ordenada.




Método 1

Definimos la función unico que tiene dos argumentos. La función, dado el número x y la lista L, detecta si x es único o esta repetido. Si el número x no está en la lista entonces retorna True, y si el número se encuentra ya en la lista entonces devuelve False.
El bucle while nos proporciona los 10 números aleatorios sin repetición que ha de llegar a tener la lista. En este caso el bucle ha de ser del tipo while, no valdría un for, ya que no conocemos el número de ciclos que serán necesarios, puesto que si no existen repeticiones serán 10 ciclos pero si las hay el número aumenta. Por cada repetición encontrada se ha de generar un nuevo x aleatorio. Los x únicos generados se anexionan a la lista con append.
Finalmente se imprime la lista L y se ordena con sort.




import random
def unico(x,L):
  esUnico=True
  for i in range(len(L)):
    if x==L[i]:
      esUnico=False
      break
  return esUnico
L=[]
j=0
while j<10:
  x=random.randint(80,99)
  if unico(x,L):
    L.append(x)
    j+=1
print(L)
L.sort()
print(L)


Método 2

Inicializamos la lista L con su primer valor, el de la posición cero. Esto se hace fuera del bucle while ya que el primer x estamos seguros de que no se repite respecto a los anteriores, ya que es el primero. Luego nos metemos en un bucle while que genera los demás x aleatorios que de momento son candidatos, hasta que no se compruebe que no están repetidos entre los elementos que ya se encuentran en la lista. Para conseguir establecer si el número candidato se ha de anexionar a la lista o no se hace usando un bucle for que contiene un condicional if. La clave está en el else que no pertenece al if sino al for.
Finalmente imprimimos la lista L y la ordenamos con sorted.

import random
L=[random.randint(80, 99)] #este es L[0]
i=1
while i<10:
  x=random.randint(80,99)
  for j in range(0, len(L)):
    if L[j]==x:
      break
  else:
    L.append(x)
    i+=1
print(L)
print(sorted(L))


Método 3

Esta es una variante del método anterior que mejora el código ya que usa en el if la instrucción in, o mejor dicho, not in, para detectar si el nuevo número aleatorio se encuentra entre los que ya se han añadido a la lista L.


import random
L=[random.randint(80, 99)] #este es L[0]
i=1
while i<10:
  x=random.randint(80,99)
  if x not in L:
    L.append(x)
    i+=1
print(L)
print(sorted(L))


Método 4

Importamos únicamente el método sample de la librería random que permite crear una lista eligiendo aleatoriamente 10 valores de un rango de números creado con range que varía entre 80 y 100 (excluido el 100).

Con sorted ordenamos la lista . Si deseamos que la ordenación sea inversa tendremos que indicarlo poniendo print(sorted(L,reverse=True)).

from random import sample
L=sample(range(80,100),10)
print(L)
print(sorted(L))


Método 5

Este método, al igual que el anterior, utiliza sample para elegir una muestra aleatoria entre los posibles valores que generamos utilizando List Comprehension.
Faltaría ordenar la lista, pero hemos preferido dejar el código así para que se vea que en dos líneas se puede llegar a obtener la lista de aleatorios sin repetición.


from random import sample
print(sample([x for x in range(80,100)],10))


Método 6

Creamos la lista L usando list y range. Esta lista contendrá todos los números enteros consecutivos entre 80 y 99. La instrucción random.shuffle(L) baraja aleatoriamente la lista L. Creamos la lista L10 que contendrá los 10 primeros elementos de la lista L. Imprimimos la lista L10. Ordenamos la lista L10 en sentido inverso usando sort. Si la queremos ordenar en sentido creciente simplemente dejaremos vacío lo que va entre sus paréntesis. Sería L10.sort().


import random
L=list(range(80,100))
random.shuffle(L) #baraja la lista
L10=L[:10] #crea otra lista con los 10 primeros elementos
print(L10)
L10.sort(reverse=True) #ordena la lista L10
print(L10)

viernes, 3 de agosto de 2018

Años bisiestos en Python

Reto: Bisiesto

Crear una función que dado un año diga si es bisiesto.



Podemos consultar la Wikipedia para saber qué años son bisiestos.
El calendario Juliano dio paso a calendario Gregoriano en 1582. Desde entonces se estableció la regla que nos dice cuando una año es bisiesto y por lo tanto tiene 366 días, en lugar de 365, ya que se añade un día más el 29 de febrero.

  • Un año es bisiesto si es múltiplo de 4, salvo que...
    • el año termine en 00, en cuyo caso, no será bisiesto, salvo que ...
      • el año sea múltiplo de 400, en cuyo caso, si será bisiesto.
Como podemos observar para que un año sea bisiesto existe una regla general (que sea múltiplo de 4) pero a esta regla general existe una excepción (que el año termine en 00, esto es, los finales de siglo) en cuyo caso el año no será bisiesto, y finalmente existe una excepción a la excepción anterior (que el año sea múltiplo de 400) en cuyo caso el año si será bisiesto.

Así por ejemplo, los años 2100, 2200, 2300 no serán bisiestos, pero el 2400 si lo será.


Método 1

Definimos una función que contiene un if con una condición lógica compleja que resume la regla que nos da el año bisiesto.




def bisiesto(x):
  if x%4==0 and (not(x%100==0) or x%400==0 ):
    texto='es bisiesto.'
  else:
    texto='es un año NO bisiesto.'
  return texto
x=int(input('Introduzca un año entre 1600 y 2500:'))
print(x,bisiesto(x))


Método 2

Generamos un año aleatorio y definimos una función que nos retornará True si se trata de una año bisiesto y nos retornará False si el año generado no es bisiesto. Con este método hemos optado por realizar varios if concatenados para resolver la lógica de los años bisiestos.

import random
random.seed()
x=random.randint(1600,2500)
def bisiesto(x):
  if x%4==0:
    if x%100==0:
      if x%400==0:
        return True
      else:
        return False
    else:
      return True
  else:
    return False
if bisiesto(x):
  print(x,'es un año bisiesto.')
elif not(bisiesto(x)):
  print(x,'no es un año bisiesto')

Nombrar elementos en CSS

En CSS si quieres afectar a algún elemento del HTML tienes varias opciones.

La mas obvia es referirse a los elementos por etiquetas, simplemente escribiendo la etiqueta como se haría en HTML sin el mayor y menor. Como esto:

 p {  
   background-color: red;  
 }  
Y el resultado seria algo a esto:

Pero si quisiéramos darle un color diferente a cada p le tendríamos que dar un nombre diferente a cada p, para ello en HTML habría que hacer algo así: 

 <p id='uno'>Y en este los dos</p>  
 <p id='dos'>estamos de colores distintos</p>  

Y para llamarlos en el CSS hay que poner un # delante del nombre y escribir los parámetros como haríamos normalmente, similar a esto:

 #uno {  
   background-color: red;  
 }  
 #dos {  
   background-color: blue;  
 }  

Y con esas dos cosas implementadas en tu código el resultado debería de ser este:
También se puede utilizar * para afectar a todos los elementos (esto también incluye el fondo).
Este seria un ejemplo:


 * {  
  margin:1;  
  padding:2;  
 }  

Series en Python

Reto: Series

Listar los números entre un valor inicial y uno final, con un cierto intervalo. Al final dar la suma de todos los valores listados.




Método 1

Establecemos tres valores concretos para las variables inicial, final e intervalo. Con el objeto de llegar a calcular la suma total creamos la variable total que inicializamos a cero. Nos metemos en un bucle for para recorrer con range todos los valores del rango usando el intervalo establecido. El objeto range nos permite recorrer un rango comenzando por el inicio, pero no llegando nunca al final exactamente. Observe que en la imagen no aparece listado el final que es 20.

La variable total actúa como acumulador sumando en cada vuelta del bucle el valor que tome la variable i en ese momento. Finalmente, y fuera del bucle imprimimos el valor de la variable total.



inicial=10
final=20
intervalo=2
total=0 #inicializamos la suma a cero
for i in range(inicial,final,intervalo):
  total+=i #la variable total actúa de acumulador
  print(i)
print('La suma es:',total)


Método 2

Generamos valores aleatorios para las variable inicial, final e intervalo. Imprimimos por pantalla los valores obtenidos. Creamos la variable i que luego usaremos en el bucle while y la inicializamos con el valor inicial. Creamos la lista L y la inicializamos como una lista vacía. La variable total inicialmente valdrá cero. Nos metemos en un bucle while que durará mientras la variable i sea menor que el valor final. Con append vamos añadiendo a la lista L los valores del intervalo dados por la variable i. Dentro del bucle while incrementamos el valor de la variable i con el importe del intervalo. Acumulamos los valores obtenidos en la variable total. Fuera del bucle imprimimos la lista L y mostramos el importe de la suma.



import random
random.seed() #barajamos la serie de números aleatorios
inicial=random.randint(100,130)
final=inicial+random.randint(10,20)
intervalo=random.randint(2,5)
print('inicial=',inicial)
print('final=',final)
print('intervalo=',intervalo)
i=inicial
L=[] #inicializamos L como una lista vacía
total=0 #inicializamos la suma a cero
while i<final:
  L.append(i) #añadimos el valor i a la lista L
  i+=intervalo #aumentamos el valor del contador
  total+=i
print(L) #imprimimos la lista
print('La suma es:',total)

Operaciones con números en Python

Reto: Operaciones con números

Dados dos números hacer con ellos las operaciones básicas.




Consulte la entrada titulada:



Método 1

Inicialmente hacemos que la variable x valga 15 y la variable y tome un valor de 3. Calculamos e imprimimos la suma, resta, multiplicación y división. Luego damos nuevos valores a x e y, en una sola línea de código. Calculamos la potencia x elevado a y. Damos a x el valor 11 y calculamos la división entera y el módulo.

x=15
y=3
print(x,'+',y,'=',x+y)
print(x,'-',y,'=',x-y)
print(x,'*',y,'=',x*y)
print(x,'/',y,'=',x/y)
x,y=2,3
print(x,'elevado a',y,'=',x**y)
x=11
print(x,'división entera entre',y,'=',x//y)
print(x,'módulo',y,'=',x%y)
#operadores lógicos
print(x,'es mayor que',y,x>y)
print(x,'es menor que',y,x<y)
print(y,'<',x,'<20',y<x<20)


Método 2

Generamos aleatoriamente los valores x e y. Calculamos al suma, resta, multiplicación y potencia. Para la división creamos una función con un control de excepciones para evitar la división por cero. Con try hacemos la división normal pero si detectamos que se puede llegar a producir un erro de ZeroDivisionError lo que hacemos con except es evitar ese error y en su lugar la función retorna un texto que informa del motivo de no haber realizado la división. Con ello evitamos que el programa lance un error que detenga la ejecución y confunda al usuario. También creamos una función para la división entera y otra para el cálculo del módulo con el control de excepciones correspondiente.


import random
x=random.randrange(1,10,2) #genera impares entre 1 y 9
y=random.randrange(3) #genera 0,1,2
print(x,'+',y,'=',x+y)
print(x,'-',y,'=',x-y)
print(x,'*',y,'=',x*y)
print(x,'elevado a',y,'=',x**y)
def div(x,y):
    try: return x/y
    except ZeroDivisionError: return 'error: denominador cero'
print(x,'/',y,'=',div(x,y))
def divent(x,y):
    try: return x//y
    except ZeroDivisionError: return 'error: denominador cero'
print(x,'división entera entre',y,'=',divent(x,y))
def modulo(x,y):
    try: return x%y
    except ZeroDivisionError: return 'error: denominador cero'
print(x,'módulo',y,'=',modulo(x,y))


Longitud de una cadena en Python

Reto: Longitud de una cadena

Crear una función que calcule la longitud de una cadena alfanumérica. Crear otra función que dada una cadena devuelva el primer caracter en mayúsculas y el resto en minúsculas. Pasar una palabra por ambas funciones y dar el resultado.




Método 1

Para calcular la longitud de una cadena lo mejor es usar len que se verá en el método 2, pero hemos querido usar aquí una forma alternativa de conseguirlo. De la misma manera para convertir una cadena en un nombre propio, existe capitalize que usaremos en el método 2, pero hemos querido ver cómo se puede conseguir sin usar esta función propia de Python. Primero usamos lower para pasar todo a minúsculas, y luego usamos upper aplicado al primer carácter para que esté mayúsculas.

def longitudCadena(x):
  contador=0
  for i in x:
    contador+=1
  return contador
def nombrePropio(x):
  y=x.lower()
  return y[0].upper()+y[1:]
x=input('Indique una palabra') or 'mADRId'
print(nombrePropio(x),'tiene',longitudCadena(x),'caracteres.')


Método 2

Usamos len para obtener la longitud del stringcapitalize para convertirlo en nombre propio. usaremos.

def longitudCadena(x):
  return len(x)
def nombrePropio(x):
  return x.capitalize()
x=input('Indique una palabra') or 'maDRid'
print(nombrePropio(x),'tiene',longitudCadena(x),'caracteres.') 

Capitalización compuesta en Python

Reto: Capitalización compuesta

Crear una aplicación que trabaje con la ley de capitalización compuesta.




Método 1

Preguntamos al usuario por el capital inicial, los años y el tipo de interés anual. Imprimimos el montante final alcanzado redondeado a dos decimales.

C=float(input('Introduzca el capital inicial') or 1000)
print('Capital inicial=',C)
n=float(input('Introduzca los años') or 3)
print('años=',n)
i=float(input('Introduzca el tipo de interés, por ejemplo 0.08 para 8%') or .08)
print('Tipo de interés anual=',i)
print('Capital final=',round(C*(1+i)**n,2))


Método 2

Generamos de forma aleatoria el capital inicial, el tiempo y el tanto de interés. Imprimimos el montante final que calcula una función.

import random
def montante(C,n,i):
  return C*(1+i)**n
C=random.randint(1000,9999)
print('Capital inicial=',C)
n=random.randint(1,10)
print('años=',n)
i=random.randint(2,20)/100
print('Tipo de interés anual=',i)
print('Capital final=',round(montante(C,n,i),2))

lunes, 16 de julio de 2018

Selección de elementos de un vector en R

Ya hemos visto que podemos usar los corchetes [] para obtener uno o varios elementos de un vector. Ahora vamos a conseguir selecciones más interesantes e incluso introduciremos filtros.



Operadores lógicos


<  menor que
>  mayor que
<= menor o igual que
>= mayor o igual que
== igual (comparación)
!= distinto (no igual)


a <- 5
a>4                   # TRUE  
a <- c(1,2,3,4,5)
a<=2                  # TRUE  TRUE FALSE FALSE FALSE
#Creamos el vector b
b <- a>=3
b                     # FALSE FALSE  TRUE  TRUE  TRUE
a*b                   # 0 0 3 4 5
a==b                  # FALSE FALSE FALSE FALSE FALSE
a!=b                  # TRUE TRUE TRUE TRUE TRUE



Selección de elementos de un vector

Observe que en el código siguiente la expresión beneficio[gano] nos permite seleccionar parte de un vector gracias a que en los corchetes [] hemos añadido un filtro o selección. Este filtro no es como hemos visto anteriormente indicando que elementos concretos queremos sino que se realiza introduciendo un vector denominado gano donde todos sus elementos son condiciones lógicas TRUE o FALSE. Esto actúa de filtro y nos devuelve únicamente lo elementos que cumplen ser verdaderos TRUE.


#Asignamos los días de la semana a un vector
dias <- c('Lun','Mar','Mie','Jue','Vie')
#Creamos un vector de perdidas y ganancias
beneficio <- c(-19,-86,125,-343,71)
#Nombramos el vector
names(beneficio) <- dias
beneficio #Imprimimos el vector ya nombrado
gano <- beneficio>0             #Creamos el vector gano con cinco booleanos
print('Vector gano:')
gano
#Creamos un vector solo con los resultados positivos
ganancias <- beneficio[gano] 
print('Estas son las ganancias: ')
ganancias



Operar con valores lógicos

Podemos asignar booleanos a variables o a vectores. Veamos algunas operaciones que se pueden realizar con valores lógicos.


#Asignamos un valor booleano a una variable
a <- TRUE
b <- FALSE
a            #Imprimimos a
b            #Imprimimos b
a*b  # 1*0=0
a*!b # 1*1=1
#Creamos los vectores v y w
v <- c(1,3,5,7,9)
w <- c(100,200,300,400,500)
#Imprimimos v, w y su suma
v
w
v+w
a & b         # AND
a | a         # OR


domingo, 15 de julio de 2018

Trabajar con vectores en R

El lenguaje de programación R está orientado al cálculo científico y en especial a la estadística por lo que el manejo de vectores se encuentra muy desarrollado.

Creación de vectores

Podemos crear vectores con datos numéricos, string o booleanos pero sin mezclar tipos. Si mezclamos se convierten todos a string.

# Asignamos valores al vector v
v <- c(1,-3,5,7,9.5)
w <- c(100,200,300,400,500)
# Imprimimos v, w
v
w
# Los vectores pueden contener strings
character_vector <- c("a", "b", "c")
character_vector
# Los vectores pueden contener valores lógicos
boolean_vector <- c(TRUE, FALSE, TRUE)
boolean_vector


Nombrar vectores

En algunos casos puede ser necesario dar un nombre a los valores de un vector.


#Vector de pérdidas y ganancias diarias de una semana
pg <- c(170, -20, 50, -160, 290)
#Imprimimos el vector pg aún sin ser nombrado
pg
#Asignamos días como nombres del vector pg
names(pg) <- c("Lun", "Mar", "Mie", "Jue", "Vie")
# Imprimimos el vector después de ser nombrado
pg
#Podemos asignar los días de la semana a un vector
dias <- c('Lun','Mar','Mie','Jue','Vie')
dias
#Creamos otro vector de perdidas y ganancias
beneficio <- c(-19,-86,125,-343,71)
#Nombramos el vector
names(beneficio) <- dias
beneficio #Imprimimos el vector ya nombrado

Sumar vectores

La suma de vectores da como resultado otro vector que es suma de los elementos de ambos vectores. Por el contrario si utilizamos la función sum() sobre un vector el resultado será la suma de todos los elementos de ese vector.

a <- c(1, 3, 4) 
b <- c(2, 2, 3)
c <- a + b       #El vector c es suma de los vectores a y b
a                #Imprimimos a
b                #Imprimimos b
c                #Imprimimos c
#Elevamos los elementos de a usando como potencias los de b
#El resultado no se asigna a ninguna variable simplemente se imprime
a^b
#Suma de todos los elementos de un vector
sum(c)
#Comprobamos que la suma de todos los elementos de c es igual a los de a y b juntos
sum(c)==sum(a+b)


Elementos de un vector

Podemos trabajar con elementos individuales o conjuntos de elementos de un vector usando los corchetes [].


beneficio <- c(-19,-86,125,-343,71)
print('Imprimimos el vector sin nombrar')
beneficio
print('Imprimimos el segundo elemento del vector')
beneficio[2]
dias <- c('Lun','Mar','Mie','Jue','Vie')
#Nombramos el vector
names(beneficio) <- dias
print('Ahora al imprimir el 2º elemento del vector se verá el nombre')
beneficio[2]
print('Imprimimos el valor del viernes')
beneficio['Vie']
print('Imprimimos el valor del miércoles y del viernes')
beneficio[c('Mie','Vie')]
print('Veamos los tres elementos centrales')
beneficio[c(2, 3, 4)]
print('Días centrales entre 2 y 4')
centrales <- beneficio[2:4]
centrales
#cat imprime dos elementos separados por coma
#mean calcula la media de los elementos de un vector
cat('La media de los días centrales es',mean(centrales))


sábado, 14 de julio de 2018

Introducción a R

El lenguaje de programación R especializado en estadística y cálculo científico se está expandiendo estos años como alternativa gratuita a otros como SPSS o MatLab. Aunque como alternativa a MatLab tenemos Octave del que puede verse la entrada titulada Comandos básicos en Octave.

Podemos instalar R en nuestro PC o ejecutarlo desde alguna página web donde esté disponible de forma online. Por ejemplo http://rextester.com/l/r_online_compiler

Parte del material introductorio sobre R se ha obtenido adaptando los ejemplos contenidos en el siguiente repositorio de  un curso de DataCamp.



Operaciones básicas

Veamos algunas operaciones básicas en R.

#suma (+)
2+3
#resta (-)
8-5
#producto (*)
5*8
#división (/)
19/17
#potenciación(^)
2^3
#módulo (%%)
5%%2

La salida es la siguiente.

Asignación de variables

Veamos como se asignan variables numéricas, booleanos y strings.

# Asignación de valores a x e y
x <- 1
y <- 12/(4+2)+3
# Imprimimos el valor de las variables
x
y
# Asignación de booleanos
a <- TRUE
b <- FALSE
# Imprimimos las variables a y b
a
b
# Asignación de cadenas alfanuméricas
p <- 'Madrid'
q <- "Ciudad de México"
# Imprimimos los dos variables string
p
q

La salida es la siguiente.

Clase de valor: class

Para determinar el tipo de valor de una variable se usa class().

# Declare variables of different types:
mi_numero <- 15
mi_cadena <- "Madrid"
mi_logico <- TRUE

# Vemos de que clase son las variables
class(mi_numero)
class(mi_cadena)
class(mi_logico)

La salida es la siguiente.


viernes, 13 de julio de 2018

Media ponderada

Reto: Media ponderada

Calcular la media ponderada de una serie de valores.




Vamos a calcular la media aritmética y la media ponderada de una serie de exámenes. Conocemos la nota de las prueba y su peso. Los pesos vienen dados en tanto por uno y han de sumar uno, que equivale al 100%. Hemos puesto unos datos para que diferencien bien ambas medias. La media aritmética saldrá 6,5 y la ponderara será de 8,37, ya que los pesos mayores recaen en los exámenes donde se ha obtenido mejor calificación.

Método 1

Disponemos de las notas (lista x) y de los pesos (lista w). La condición sum(w)==1 ha de arrojar el valor True, lo que permite comprobar que los pesos suman uno. Inicializamos la variable arit que calculará la media aritmética. Nos metemos en un blucle for que recorrerá todas las calificaciones de la lista x. En cada iteración ira acumulando las notas en la variable arit. Al finalizar el bucle dividimos el contenido de la variable arit entre el número de elementos de la lista x, de esta forma ya tendremos calculada la media aritmética y pasamos a imprimirla.
Inicializamos la variable pondera con el valor cero. Esta variable calculará la media ponderada. Nos metemos en un bucle for que recorrerá los números desde el cero hasta cinco, ya que la longitud de x es seis. En cada ciclo del bucle la variable pondera irá acumulando cada una de las calificaciones multiplicada por su peso en tanto por uno. Al finalizar el bucle la variable pondera ya contendrá la media aritmética ponderada que pasaremos a imprimir con un cierto redondeo.

#Notas de los exámenes
x=[7,4,9,3,6,10]
#Pesos de cada examen. Suman 1=100%
w=[.1,.05,.25,.06,.09,.45]
print('¿Los pesos suman 1?:',sum(w)==1.)
arit=0
for i in x:
  arit+=i
arit/=len(x)
print('Media aritmética:',arit)
pondera=0
for i in range(len(x)):
  pondera+=x[i]*w[i]
print('Media ponderada:',round(pondera,6))


Método 2

En este método utilizamos una notación condensada para los bucles for. Para la media aritmética el bucle for utiliza una única variable instrumental i, pero en el caso de la media ponderada son necesarias dos variable auxiliares i, j. También hemos tenido que emplear zip para unir las listas sobre las que operamos x y w.

x=[7,4,9,3,6,10] #Notas
w=[.1,.05,.25,.06,.09,.45] #Pesos
arit=round(sum(i for i in x)/len(x),6)
print('Media aritmética:',arit)
pondera=round(sum(i*j for i,j in zip(x,w)),6)
print('Media ponderada:',pondera)


Método 3

Importamos la librería científica NumPy que nos permite trabajar con vectores (arrays). Para calcular la media aritmética utilizamos mean que es una función disponible en la librería NumPy y que precisamente calcula la media aritmética de los valores que contiene la lista x.
Convertimos las listas x y w en los array xa y wa. La nota media ponderada se obtiene sin más que multiplicar ambos vectores y sumar su resultado.

import numpy as np
x=[7,4,9,3,6,10] #Notas
w=[.1,.05,.25,.06,.09,.45] #Pesos
arit=np.mean(x)
print('Media aritmética:',arit)
xa=np.array(x)
wa=np.array(w)
pondera=round(sum(xa*wa),6)
print('Media ponderada:',pondera)

martes, 10 de julio de 2018

Convertir monedas y billetes en Python

Reto: Conversión de monedas y billetes

Dada una cantidad de dinero indicar cuantos billetes y monedas de cada tipo son necesarios como mínmo.



Dado un cierto importe en euros deseamos conocer el mínimo número de monedas y billetes necesarios para alcanzar esa cifra. Disponemos de una lista con los tipos de billetes y monedas existentes, desde el billete de 500 € hasta la moneda de un céntimo (0,01 €). Son quince tipos de elementos entre billetes y monedas los que tenemos en la zona euro.

El procedimiento utilizado se basa en calcular un cociente entre la cifra inicial disponible en euros  y 500 que es el billete más grande. La parte entera nos dará el número de billetes de 500 € necesarios, y el resto se usará como denominador en la siguiente división. La segunda división se realiza dividiendo entre 200 que es el siguiente billete. La parte entera nos dará el número de billetes de 200 € necesarios y el resto se convertirá en el numerador de la siguiente división. Este proceso se sigue reiteradamente hasta llegar a la moneda más pequeña que es la de un céntimo.



Método 1

Definimos la lista T que contiene los quince tipos de billetes y monedas existentes en la zona euro. Inicializamos la lista S con quince ceros. Esta lista contendrá la salida obtenida indicando en cada uno de sus elementos el número de billetes y monedas necesarios de cada tipo para llegar a cubrir la cifra dada en euros y conseguir que sean mínimas las monedas y billetes utilizados. La lista S es la solución al caso práctico planteado.
Generamos aleatoriamente x que es la cifra en euros que vamos a descomponer. Utilizamos random.randint que únicamente nos permite generar números aleatorios enteros entre un par de ellos dados como argumentos. Si bien nosotros precisamos que la cifra en euros tenga dos decimales. Para ello, usamos un pequeño truco que consiste en dividir entre 100 el valor obtenido. De esta forma, lo que obtendremos para x son valores entre 1.000,00 € y 3.000,00 €.
En el algoritmo el primer paso usa x como numerador del cociente que iremos realizando reiteradamente, pero luego el numerador será el resto obtenido en el paso previo. Esto hace que tengamos que definir el primer resto como resto=x.

Nos metemos en un bucle for que recorre quince valores entre 0 y 14. Dentro del bucle usamos la función divmod que utiliza como argumentos el numerador y el denominador, y que devuelve dos valores que son la parte entera y el resto. Se podría haber obtenido el mismo resultado usando la división entera en Python (//) y el cálculo del módulo(%). Imprimimos S[i] que contiene el número de monedas y billetes necesarios del tipo T[i]. Al recorrer el bucle los quince elementos de estas listas lo que obtendremos por pantalla es un listado con todos los billetes y monedas necesarios de cada tipo para alcanzar la cifra inicial de x euros.



Finalmente lo que hacemos es comprobar que todos esos billetes y monedas multiplicados por el valor en euros de cada uno de los tipos resulte igual a la cifra x inicial. El último elemento a imprimir (total==x) es una condición que nos indicará con True si coinciden el total obtenido multiplicando y sumando los diferentes valores con el importe x inicial.

import random
T=[500,200,100,50,20,10,5,2,1,.5,.2,.1,.05,.02,.01]
S=[0]*15 #salida por tipo de billete y moneda
x=random.randint(100000,300000)/100
resto=x
print('Disponemos de',x,'euros.')
print('Se pueden descomponer en:')
for i in range(len(T)):
  S[i], resto = divmod(round(resto,6), T[i])
  print(int(round(S[i],4)),'de',T[i],'€')
print('Comprobación')
total=0
for i in range(len(T)):
  total+=S[i]*T[i]
total=round(total,6)
print(total,total==x)


Método 2

En este caso disponemos de la lista C de quince posiciones que contendrán el número de billetes y monedas disponibles inicialmente de cada tipo, que se generan de forma aleatoria. Esta composición de billetes y monedas, a priori no será óptima y lo que pretendemos es encontrar la composición dada por la lista de salida S que nos proporcione el número mínimo de monedas y billetes necesarios.

Dada la lista C vamos a calcular que importe total en euros supone este dinero. Para ello vamos a emplear dos procedimientos que luego podremos ver que coinciden.

  • El primer procedimiento requiere definir la variable suma que inicializamos con el valor cero. Nos metemos en un bucle for que recorrerá los quince elementos de la lista. Vamos calculando cada elemento C[i] de forma aleatoria y vamos obteniendo la suma acumulada multiplicando cada elemento i-ésimo de las listas T y C. De esta forma hemos obtenido el dinero inicialmente disponible que queda recogido en la variable suma.
  • El segundo procedimiento es mucho más sintético y no necesita definir la variable suma y no necesita hacer uso del bucle for anterior. Directamente podemos calcular x de forma condensada en una sola línea con la expresión sum([a * b for a, b in zip(T,C)]) que equivale a la función sumaproducto de Excel.
Una vez conocido el importe de los x euros lo primero que hacemos es usar un bucle for para mostrar en pantalla su composición según las diferentes monedas y billetes disponibles inicialmente, imprimiendo C[i] y T[i].



Luego imprimimos por pantalla la frase que indica nuestra intención es cambiar esas monedas y billetes por otra composición que sea mínima. Siguiendo la imagen, se puede ver la frase que dice 'Los 2692.38 € se pueden descomponer en:'. En esta frase el importe que se cita coincide con el que se muestra inicialmente, e ilustran los dos procedimientos vistos anteriormente. La primera cifra es x y la segunda es la variable suma.

El resto del algoritmo es igual que el del método anterior, salvo que al final no hacemos la comprobación que se hizo en el método 1, y que en este caso lo que hacemos es ver de cuántos billetes y monedas iniciales hemos partido y a cuantos hemos llegado. En general, se podrá apreciar una significativa reducción.


import random
T=[500,200,100,50,20,10,5,2,1,.5,.2,.1,.05,.02,.01]
C=[0]*15 #caja disponible
S=[0]*15 #salida por tipo de billete y moneda
suma=0
for i in range(15):
  C[i]=random.randint(0,5)
  suma+=T[i]*C[i]
x=sum([a * b for a, b in zip(T,C)]) #sumaproducto
print('Disponemos de',round(x,6),'euros.')
print('Están compuestos por:')
for i in range(len(T)):
  print(C[i],'de',T[i],'€')
print('Queremos cambiarlos por los mínimos billetes y monedas posibles.')
print('Los',round(suma,6),'€ se pueden descomponer en:')
resto=x
for i in range(len(T)):
  S[i], resto = divmod(round(resto,6), T[i])
  print(int(round(S[i],4)),'de',T[i],'€')
print('Teníamos',sum(C),'billestes y monedas','y los hemos reducido a',int(sum(S)))