├── static ├── styles │ ├── empty.css │ ├── FluxBold.ttf │ ├── ico-plane.gif │ └── style.css ├── disco.png ├── spyder.png ├── blackbox.jpg ├── cell_move.gif ├── ejes_pala.jpg ├── linkedin.png ├── pybofractal.png ├── quad_xsinx.png ├── trap_xsinx.png ├── circunferencia.png ├── download_zip.png ├── markdown_cell.gif ├── markdown_math.gif ├── plot_colormaps.png ├── perfil_yukovski.png ├── saving_notebook.png ├── transf_yukovski.png ├── download_anaconda.png ├── ejercicio_contour.png ├── aeropython_name_mini.png ├── simplification_sympy.png ├── ventana_comandos_mac.png ├── ventana_comandos_windows.png ├── mi_primer_script.py ├── polar.dat ├── maxima.py ├── test_maxima.py ├── pep8magic.py ├── orbital.py ├── notas.csv ├── temperaturas.csv └── jdcal.py ├── template ├── logos │ ├── aeropython.png │ ├── aeropython_300x185.svg │ └── aeropython.svg └── Plantilla.ipynb ├── .gitattributes ├── util └── templatify_nb.py ├── README.md ├── .gitignore ├── notebooks_completos ├── Finale.ipynb ├── Clase0_Bienvenido.ipynb └── Clase1b_Ejercicios.ipynb └── notebooks_vacios ├── Clase1b_Ejercicios.ipynb └── Clase2a_NumPy_intro.ipynb /static/styles/empty.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/disco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/disco.png -------------------------------------------------------------------------------- /static/spyder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/spyder.png -------------------------------------------------------------------------------- /static/blackbox.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/blackbox.jpg -------------------------------------------------------------------------------- /static/cell_move.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/cell_move.gif -------------------------------------------------------------------------------- /static/ejes_pala.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/ejes_pala.jpg -------------------------------------------------------------------------------- /static/linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/linkedin.png -------------------------------------------------------------------------------- /static/pybofractal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/pybofractal.png -------------------------------------------------------------------------------- /static/quad_xsinx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/quad_xsinx.png -------------------------------------------------------------------------------- /static/trap_xsinx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/trap_xsinx.png -------------------------------------------------------------------------------- /static/circunferencia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/circunferencia.png -------------------------------------------------------------------------------- /static/download_zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/download_zip.png -------------------------------------------------------------------------------- /static/markdown_cell.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/markdown_cell.gif -------------------------------------------------------------------------------- /static/markdown_math.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/markdown_math.gif -------------------------------------------------------------------------------- /static/plot_colormaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/plot_colormaps.png -------------------------------------------------------------------------------- /static/perfil_yukovski.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/perfil_yukovski.png -------------------------------------------------------------------------------- /static/saving_notebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/saving_notebook.png -------------------------------------------------------------------------------- /static/styles/FluxBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/styles/FluxBold.ttf -------------------------------------------------------------------------------- /static/styles/ico-plane.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/styles/ico-plane.gif -------------------------------------------------------------------------------- /static/transf_yukovski.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/transf_yukovski.png -------------------------------------------------------------------------------- /static/download_anaconda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/download_anaconda.png -------------------------------------------------------------------------------- /static/ejercicio_contour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/ejercicio_contour.png -------------------------------------------------------------------------------- /template/logos/aeropython.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/template/logos/aeropython.png -------------------------------------------------------------------------------- /static/aeropython_name_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/aeropython_name_mini.png -------------------------------------------------------------------------------- /static/simplification_sympy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/simplification_sympy.png -------------------------------------------------------------------------------- /static/ventana_comandos_mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/ventana_comandos_mac.png -------------------------------------------------------------------------------- /static/ventana_comandos_windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AeroPython/Curso-AeroPython-UC3M/HEAD/static/ventana_comandos_windows.png -------------------------------------------------------------------------------- /static/mi_primer_script.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | print("Hola gente del curso de AeroPython") 4 | print("¿Cuántos sois hoy en clase?") 5 | 6 | number = input() 7 | number = int(number) 8 | root = math.sqrt(number) 9 | 10 | print("Ufff! eso es un montón! espero que aprendáis mucho") 11 | print("Por cierto, la raiz de %i es %f" %(number, root)) 12 | -------------------------------------------------------------------------------- /static/polar.dat: -------------------------------------------------------------------------------- 1 | # Polar data for a certain airplane 2 | # 1st line: C_L 3 | # 2rd line: C_D 4 | 5 | -0.9100 -0.7200 -0.4800 -0.2700 -0.0600 0.1600 0.3100 0.4700 0.6000 0.8200 1.0200 1.2000 1.2400 1.1500 1.0000 0.8000 6 | 0.0538 0.0438 0.0316 0.0245 0.0228 0.0232 0.0262 0.0301 0.0348 0.0461 0.0608 0.0771 0.0814 0.0900 0.0950 0.1000 7 | -------------------------------------------------------------------------------- /static/maxima.py: -------------------------------------------------------------------------------- 1 | # Advanced Scientific Programming in Python, autumn school, Trento, 2010 2 | # Day 1, Exercise 1 (unit testing and coverage) 3 | # Author: Pietro Berkes 4 | 5 | 6 | def find_maxima(x): 7 | """Halla los índices de los máximos relativos""" 8 | idx = [] 9 | N = len(x) 10 | if x[1] < x[0]: 11 | idx.append(0) 12 | for i in range(1, N - 1): 13 | if x[i-1] < x[i] and x[i+1] < x[i]: 14 | idx.append(i) 15 | if x[-2] < x[-1]: 16 | idx.append(N - 1) 17 | return idx 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /util/templatify_nb.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | import os.path 3 | import json 4 | 5 | NOTEBOOK_NAME = "Clase3a_Entrada-Salida-Algebra-Lineal" 6 | TEMPLATE_NAME = "Template" 7 | IPYNB_EXT = ".ipynb" 8 | 9 | with open(NOTEBOOK_NAME + IPYNB_EXT, 'r') as fp: 10 | contents = json.load(fp) 11 | 12 | with open(TEMPLATE_NAME + IPYNB_EXT, 'r') as fp: 13 | template = json.load(fp) 14 | 15 | extra_cells = template['worksheets'][0]['cells'][-10:] 16 | contents['worksheets'][0]['cells'].extend(extra_cells) 17 | 18 | with open(NOTEBOOK_NAME + '_TEMPLATED' + IPYNB_EXT, 'w') as fp: 19 | json.dump(contents, fp) 20 | 21 | -------------------------------------------------------------------------------- /static/test_maxima.py: -------------------------------------------------------------------------------- 1 | from maxima import find_maxima 2 | 3 | def test1(): 4 | lista = [1, 2, 1] 5 | resultado_esperado = [1] 6 | resultado = find_maxima(lista) 7 | assert resultado == resultado_esperado 8 | 9 | 10 | def test2(): 11 | lista = [1, 2, 3, 2, 1] 12 | resultado_esperado = [2] 13 | resultado = find_maxima(lista) 14 | assert resultado == resultado_esperado 15 | 16 | 17 | def test3(): 18 | lista = [1, 2, 3] 19 | resultado_esperado = [2] 20 | resultado = find_maxima(lista) 21 | assert resultado == resultado_esperado 22 | 23 | 24 | test1() 25 | test2() 26 | test3() 27 | -------------------------------------------------------------------------------- /static/pep8magic.py: -------------------------------------------------------------------------------- 1 | # IPython magic to check for PEP8 compliance. 2 | # Author: Juan Luis Cano 3 | 4 | """IPython magic to check for PEP8 compliance. 5 | 6 | To use it, type 7 | 8 | ```%load_ext pep8magic``` 9 | 10 | and then 11 | 12 | ```%%pep8 13 | if 6*9==42:print("Something fundamentally wrong..." ) 14 | ``` 15 | 16 | to see PEP8 failures. 17 | 18 | """ 19 | 20 | import pep8 as _pep8 21 | 22 | 23 | def pep8(line, cell): 24 | lines = cell.splitlines(True) 25 | lines[-1] += '\n' 26 | fchecker = _pep8.Checker(lines=lines, 27 | show_source=True) 28 | report = fchecker.check_all() 29 | if report == 0: 30 | print("This code is PEP8-compliant!") 31 | 32 | 33 | def load_ipython_extension(ipython): 34 | ipython.register_magic_function(pep8, magic_kind='cell') 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Curso AeroPython UC3M 2 | 3 | AeroPython 4 | 5 | ## [Juan Luis Cano](http://es.linkedin.com/in/juanluiscanor) ([@Pybonacci](https://twitter.com/Pybonacci)) y [Álex Sáez](https://www.linkedin.com/in/alejandrosaezm) ([@Alex__S12](https://twitter.com/Alex__S12)) 6 | 7 | __Curso de iniciación a Python aplicado a la Ingeniería Aeroespacial celebrado en la UC3M__ 8 | 9 | __Si acabas de llegar__, no tienes instalado Python o no conoces el Notebook de IPython te recomendamos que leas [esta introducción](http://nbviewer.ipython.org/github/AeroPython/Curso-AeroPython-UC3M/blob/master/notebooks_completos/Clase0_Bienvenido.ipynb). En ella aprenderás cómo descargar y utilizar el material del curso. 10 | 11 | __Si sólo quieres echar un vistazo__, puedes visualizar los notebooks de cada clase en: 12 | http://nbviewer.ipython.org/github/AeroPython/Curso-AeroPython-UC3M/tree/master/notebooks_completos/ 13 | 14 | __[Primera edición](http://pybonacci.org/2015/09/17/curso-aeropython-en-la-uc3m/):__ octubre 2015 15 | 16 | Licencia Creative Commons
Curso AeroPython por Juan Luis Cano Rodriguez y Alejandro Sáez Mollejo se distribuye bajo una Licencia Creative Commons Atribución 4.0 Internacional. 17 | -------------------------------------------------------------------------------- /static/orbital.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from astropy.coordinates import angles 3 | 4 | 5 | k_Sun = 132749351440.0 6 | 7 | 8 | def rv2coe(k, a, ecc, inc, raan, argp, nu): 9 | """Convierte elementos keplerianos a vectores r y v. 10 | 11 | Parámetros 12 | ========== 13 | k : float 14 | Parámetro gravitacional (km^3 / s^2) 15 | a : float 16 | Semieje mayor (km) 17 | ecc : float 18 | Excentricidad 19 | inc : float 20 | Inclinación (rad) 21 | raan : float 22 | Ascensión recta del nodo ascendente (rad) 23 | argp : float 24 | Argumento del perigeo (rad) 25 | nu : float 26 | Anomalía verdadera (rad) 27 | 28 | Devuelve 29 | ======== 30 | r, v : arrays 31 | Vectores posición (km) y velocidad (km / s) 32 | 33 | """ 34 | p = a * (1 - ecc ** 2) 35 | r_pqw = p * np.array([np.cos(nu) / (1 + ecc * np.cos(nu)), 36 | np.sin(nu) / (1 + ecc * np.cos(nu)), 37 | 0]) 38 | v_pqw = np.sqrt(k / p) * np.array([-np.sin(nu), 39 | ecc + np.cos(nu), 40 | 0]) 41 | r_ijk = transform(r_pqw, -argp, 'z') 42 | r_ijk = transform(r_ijk, -inc, 'x') 43 | r_ijk = transform(r_ijk, -raan, 'z') 44 | v_ijk = transform(v_pqw, -argp, 'z') 45 | v_ijk = transform(v_ijk, -inc, 'x') 46 | v_ijk = transform(v_ijk, -raan, 'z') 47 | return r_ijk, v_ijk 48 | 49 | 50 | def rotate(vec, angle, axis): 51 | """Rotates the coordinate system around axis 1, 2 or 3 a CCW angle. 52 | 53 | Parameters 54 | ---------- 55 | vec : array 56 | Dimension 3 vector. 57 | ax : int 58 | Axis to be rotated. 59 | angle : float 60 | Angle of rotation (rad). 61 | 62 | """ 63 | assert vec.shape == (3,) 64 | rot = np.eye(3) 65 | if axis == 'x': 66 | sl = slice(1, 3) 67 | elif axis == 'y': 68 | sl = slice(0, 3, 2) 69 | elif axis == 'z': 70 | sl = slice(0, 2) 71 | rot[sl, sl] = np.array([ 72 | [np.cos(angle), np.sin(angle)], 73 | [-np.sin(angle), np.cos(angle)] 74 | ]) 75 | return np.dot(rot, vec) 76 | 77 | 78 | def transform(vector, angle, axis): 79 | """Rotates a coordinate system around axis a positive right-handed angle. 80 | 81 | Notes 82 | ----- 83 | This is a convenience function, equivalent to 84 | `rotate(vec, -angle, axis, unit)`. 85 | Refer to the documentation of that function for further information. 86 | 87 | """ 88 | return rotate(vector, -angle, axis) -------------------------------------------------------------------------------- /static/notas.csv: -------------------------------------------------------------------------------- 1 | NOTA TEST 2 | 2.9 3 | 4.3 4 | 3.9 5 | 0.0 6 | 4.1 7 | 7.3 8 | 2.3 9 | 5.6 10 | 2.9 11 | 3.9 12 | 4.6 13 | 6.3 14 | 2.1 15 | 2.1 16 | 6.5 17 | 1.9 18 | 0.0 19 | 6.5 20 | 2.5 21 | 5.1 22 | 5.3 23 | 6.3 24 | 5.4 25 | 5.3 26 | 5.3 27 | 2.0 28 | 3.5 29 | 4.4 30 | 5.5 31 | 3.6 32 | 3.9 33 | 2.5 34 | 4.1 35 | 3.0 36 | 4.6 37 | 4.0 38 | 6.3 39 | 0.6 40 | 2.4 41 | 6.5 42 | 2.3 43 | 4.6 44 | 6.9 45 | 5.1 46 | 5.4 47 | 5.3 48 | 4.5 49 | 6.5 50 | 2.1 51 | 5.5 52 | 3.4 53 | 8.1 54 | 4.0 55 | 1.9 56 | 1.6 57 | 4.3 58 | 4.6 59 | 5.4 60 | 1.0 61 | 6.5 62 | 5.5 63 | 4.9 64 | 4.0 65 | 5.3 66 | 3.5 67 | 4.4 68 | 2.8 69 | 5.4 70 | 3.5 71 | 2.3 72 | 4.8 73 | 2.1 74 | 6.6 75 | 0.5 76 | 2.1 77 | 3.1 78 | 3.4 79 | 5.9 80 | 3.4 81 | 4.3 82 | 1.5 83 | 5.5 84 | 4.4 85 | 1.9 86 | 4.4 87 | 2.9 88 | 3.9 89 | 5.8 90 | 2.8 91 | 3.0 92 | 1.5 93 | 2.6 94 | 2.9 95 | 3.4 96 | 5.4 97 | 3.6 98 | 4.6 99 | 5.0 100 | 1.4 101 | 4.3 102 | 4.6 103 | 3.1 104 | 2.0 105 | 3.6 106 | 4.0 107 | 2.5 108 | 3.0 109 | 5.1 110 | 6.4 111 | 3.5 112 | 5.8 113 | 4.1 114 | 5.9 115 | 4.0 116 | 6.4 117 | 2.3 118 | 7.0 119 | 1.4 120 | 3.5 121 | 4.4 122 | 2.9 123 | 5.1 124 | 3.4 125 | 4.8 126 | 4.6 127 | 4.3 128 | 6.9 129 | 5.4 130 | 4.0 131 | 3.3 132 | 1.4 133 | 1.9 134 | 3.8 135 | 3.4 136 | 3.6 137 | 3.8 138 | 6.3 139 | 4.8 140 | 4.0 141 | 6.8 142 | 4.0 143 | 3.6 144 | 4.4 145 | 4.1 146 | 6.0 147 | 4.1 148 | 5.6 149 | 3.9 150 | 4.6 151 | 5.0 152 | 6.5 153 | 3.5 154 | 5.5 155 | 4.6 156 | 4.8 157 | 4.6 158 | 6.5 159 | 4.1 160 | 4.4 161 | 5.3 162 | 3.6 163 | 7.1 164 | 4.6 165 | 2.1 166 | 3.3 167 | 3.9 168 | 4.0 169 | 4.4 170 | 0.9 171 | 4.3 172 | 2.4 173 | 2.9 174 | 3.6 175 | 1.4 176 | 2.8 177 | 2.5 178 | 6.6 179 | 0.0 180 | 5.1 181 | 0.0 182 | 5.1 183 | 4.0 184 | 2.6 185 | 4.1 186 | 4.6 187 | 3.1 188 | 4.4 189 | 2.8 190 | 2.8 191 | 5.6 192 | 3.9 193 | 4.4 194 | 4.1 195 | 0.3 196 | 2.4 197 | 3.3 198 | 2.5 199 | 4.3 200 | 2.5 201 | 4.5 202 | 4.8 203 | 4.3 204 | 3.3 205 | 6.0 206 | 2.3 207 | 4.5 208 | 3.4 209 | 4.5 210 | 2.3 211 | 4.5 212 | 2.5 213 | 6.4 214 | 7.0 215 | 5.8 216 | 3.4 217 | 5.1 218 | 4.9 219 | 8.5 220 | 3.0 221 | 3.3 222 | 3.3 223 | 2.6 224 | 1.8 225 | 2.9 226 | 4.3 227 | 2.1 228 | 4.8 229 | 5.3 230 | 3.1 231 | 5.0 232 | 4.6 233 | 3.1 234 | 5.6 235 | 5.5 236 | 4.3 237 | 4.5 238 | 5.4 239 | 4.3 240 | 1.5 241 | 3.9 242 | 5.4 243 | 1.8 244 | 3.5 245 | 5.3 246 | 2.6 247 | 3.5 248 | 3.0 249 | 4.9 250 | 3.5 251 | 3.4 252 | 2.0 253 | 4.5 254 | 5.3 255 | 3.0 256 | 1.6 257 | 4.8 258 | 3.8 259 | 0.6 260 | 4.1 261 | 5.4 262 | 7.5 263 | 0.6 264 | 2.6 265 | 2.1 266 | 3.8 267 | 3.3 268 | 5.4 269 | 3.6 270 | 2.4 271 | 4.6 272 | 0.9 273 | 5.8 274 | 4.4 275 | 1.0 276 | 3.6 277 | 6.3 278 | 4.4 279 | 7.5 280 | 5.9 281 | 0.5 282 | 4.3 283 | 2.4 284 | 6.0 285 | 4.6 286 | 5.1 287 | 6.1 288 | 4.0 289 | 4.5 290 | 7.9 291 | 3.5 292 | 3.1 293 | 5.0 294 | 6.3 295 | 4.9 296 | 5.9 297 | 4.6 298 | 5.8 299 | 5.4 300 | 0.1 301 | 1.8 302 | 5.1 303 | 4.0 304 | 2.4 305 | 4.6 306 | 4.9 307 | 3.1 308 | 1.4 309 | 4.0 310 | 3.6 311 | 4.3 312 | 3.8 313 | 4.4 314 | 4.8 315 | 5.1 316 | 4.0 317 | 0.0 318 | 2.1 319 | 5.9 320 | 6.3 321 | 3.1 322 | 6.0 323 | 3.4 324 | 1.9 325 | 5.6 326 | 5.3 327 | 4.8 328 | 2.6 329 | 5.6 330 | 4.8 331 | 5.4 332 | 3.4 333 | 5.3 334 | 4.1 335 | 3.8 336 | 3.6 337 | 3.9 338 | 2.0 339 | 3.5 340 | 4.0 341 | 3.6 342 | 0.6 343 | 2.4 344 | 3.9 345 | 4.1 346 | 2.8 347 | 3.0 348 | 5.1 349 | 5.4 350 | 3.9 351 | 3.3 352 | 3.8 353 | 2.5 354 | 0.6 355 | 2.8 356 | 2.9 357 | 7.0 358 | 6.0 359 | 2.8 360 | 4.0 361 | 4.9 362 | 4.8 363 | 2.8 364 | 2.0 365 | 4.0 366 | 2.6 367 | 3.1 368 | 2.9 369 | 6.5 370 | 4.3 371 | 2.1 372 | 3.9 373 | 4.3 374 | 0.0 375 | 7.4 376 | 3.9 377 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | 217 | #Ipython Notebook 218 | # .ipynb_checkpoints (added by alex s) 219 | .ipynb_checkpoints/ 220 | -------------------------------------------------------------------------------- /notebooks_completos/Finale.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "\"AeroPython\"\n", 12 | "\n", 13 | "# *Finale*: ¿Y ahora qué?" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": { 19 | "slideshow": { 20 | "slide_type": "slide" 21 | } 22 | }, 23 | "source": [ 24 | "## Más material de aprendizaje\n", 25 | "\n", 26 | "* Cursos AeroPython \n", 27 | "* Artículos y tutoriales en Pybonacci \n", 28 | "* SciPy Lecture Notes \n", 29 | "* Curso de Python para científicos e ingenieros \n", 30 | "* Vídeos PyConES " 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": { 36 | "slideshow": { 37 | "slide_type": "slide" 38 | } 39 | }, 40 | "source": [ 41 | "## Dónde pedir ayuda\n", 42 | "\n", 43 | "* Python-es, la lista de Python en castellano \n", 44 | "* StackOverflow, preguntas y respuestas sobre programación " 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": { 50 | "slideshow": { 51 | "slide_type": "fragment" 52 | } 53 | }, 54 | "source": [ 55 | "* ¿Próximamente StackOverflow en español? " 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": { 61 | "slideshow": { 62 | "slide_type": "fragment" 63 | } 64 | }, 65 | "source": [ 66 | "* Lista AeroPython " 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": { 72 | "slideshow": { 73 | "slide_type": "slide" 74 | } 75 | }, 76 | "source": [ 77 | "## La comunidad española\n", 78 | "\n", 79 | "* Reuniones Python Madrid \n", 80 | "\n", 81 | "![Python Madrid](http://photos3.meetupstatic.com/photos/event/c/1/3/b/event_442069467.jpeg) ![Mario Pérez](http://photos1.meetupstatic.com/photos/event/c/1/3/a/event_442069466.jpeg)" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": { 87 | "slideshow": { 88 | "slide_type": "subslide" 89 | } 90 | }, 91 | "source": [ 92 | "* Conferencias Python España (PyConES) \n", 93 | "\n", 94 | "![PyConES 2014](http://2014.es.pycon.org/static/fotos/0196_081114_pycones_2014.jpg)" 95 | ] 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "metadata": { 100 | "slideshow": { 101 | "slide_type": "subslide" 102 | } 103 | }, 104 | "source": [ 105 | "* PyLadies Spain \n", 106 | "\n", 107 | "![PyLadies Spain](http://2014.es.pycon.org/static/fotos/0194_091114_pycones_2014.jpg)" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": { 113 | "slideshow": { 114 | "slide_type": "slide" 115 | } 116 | }, 117 | "source": [ 118 | "## ¿Comunidad AeroPython?\n", 119 | "\n", 120 | "Todo depende de ti ;)\n", 121 | "\n", 122 | " ![AeroPython team](http://2014.es.pycon.org/static/fotos/0202_091114_pycones_2014.jpg)" 123 | ] 124 | } 125 | ], 126 | "metadata": { 127 | "celltoolbar": "Slideshow", 128 | "kernelspec": { 129 | "display_name": "Python 3", 130 | "language": "python", 131 | "name": "python3" 132 | }, 133 | "language_info": { 134 | "codemirror_mode": { 135 | "name": "ipython", 136 | "version": 3 137 | }, 138 | "file_extension": ".py", 139 | "mimetype": "text/x-python", 140 | "name": "python", 141 | "nbconvert_exporter": "python", 142 | "pygments_lexer": "ipython3", 143 | "version": "3.4.3" 144 | } 145 | }, 146 | "nbformat": 4, 147 | "nbformat_minor": 0 148 | } 149 | -------------------------------------------------------------------------------- /static/styles/style.css: -------------------------------------------------------------------------------- 1 | /* This template is inspired in the one used by Lorena Barba 2 | in the numerical-mooc repository: https://github.com/numerical-mooc/numerical-mooc 3 | We thank her work and hope you also enjoy the look of the notobooks with this style */ 4 | 5 | 6 | 7 | El estilo se ha aplicado =) 8 | 9 | 146 | 162 | -------------------------------------------------------------------------------- /template/logos/aeropython_300x185.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | aeropython logo 16 | 18 | 21 | 27 | 28 | 31 | 37 | 38 | 41 | 47 | 48 | 49 | 51 | 52 | 54 | image/svg+xml 55 | 57 | aeropython logo 58 | september 2015 59 | 60 | 61 | Juan Luis Cano 62 | 63 | 64 | 65 | 66 | Equipo Aeropython 67 | 68 | 69 | 70 | 71 | 72 | 76 | 79 | 87 | 88 | 91 | 95 | Aero 105 | Python 115 | 116 | 117 | 120 | 124 | 125 | 128 | 132 | 136 | 139 | 144 | 149 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /template/logos/aeropython.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 25 | 28 | 34 | 35 | 38 | 44 | 45 | 48 | 54 | 55 | 56 | 78 | 81 | 82 | 84 | 85 | 87 | image/svg+xml 88 | 90 | 91 | 92 | 93 | 94 | 100 | 104 | 107 | 112 | 115 | 122 | 129 | 136 | 144 | 145 | 146 | 149 | Aero 161 | Python 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /static/temperaturas.csv: -------------------------------------------------------------------------------- 1 | STATION,DATE,TMAX,TMIN 2 | GHCND:USW00094728,20130101,44,-33 3 | GHCND:USW00094728,20130102,6,-56 4 | GHCND:USW00094728,20130103,0,-44 5 | GHCND:USW00094728,20130104,28,-11 6 | GHCND:USW00094728,20130105,56,0 7 | GHCND:USW00094728,20130106,78,11 8 | GHCND:USW00094728,20130107,72,28 9 | GHCND:USW00094728,20130108,89,17 10 | GHCND:USW00094728,20130109,94,39 11 | GHCND:USW00094728,20130110,83,44 12 | GHCND:USW00094728,20130111,78,28 13 | GHCND:USW00094728,20130112,83,56 14 | GHCND:USW00094728,20130113,100,61 15 | GHCND:USW00094728,20130114,133,33 16 | GHCND:USW00094728,20130115,33,17 17 | GHCND:USW00094728,20130116,28,0 18 | GHCND:USW00094728,20130117,61,17 19 | GHCND:USW00094728,20130118,17,-39 20 | GHCND:USW00094728,20130119,106,-11 21 | GHCND:USW00094728,20130120,117,-11 22 | GHCND:USW00094728,20130121,0,-33 23 | GHCND:USW00094728,20130122,-28,-106 24 | GHCND:USW00094728,20130123,-67,-117 25 | GHCND:USW00094728,20130124,-56,-111 26 | GHCND:USW00094728,20130125,-44,-106 27 | GHCND:USW00094728,20130126,-28,-94 28 | GHCND:USW00094728,20130127,11,-72 29 | GHCND:USW00094728,20130128,22,-17 30 | GHCND:USW00094728,20130129,94,22 31 | GHCND:USW00094728,20130130,150,39 32 | GHCND:USW00094728,20130131,161,-11 33 | GHCND:USW00094728,20130201,-6,-44 34 | GHCND:USW00094728,20130202,-17,-72 35 | GHCND:USW00094728,20130203,-11,-44 36 | GHCND:USW00094728,20130204,-11,-50 37 | GHCND:USW00094728,20130205,0,-22 38 | GHCND:USW00094728,20130206,39,-17 39 | GHCND:USW00094728,20130207,0,-33 40 | GHCND:USW00094728,20130208,11,-28 41 | GHCND:USW00094728,20130209,0,-61 42 | GHCND:USW00094728,20130210,22,-78 43 | GHCND:USW00094728,20130211,72,11 44 | GHCND:USW00094728,20130212,67,22 45 | GHCND:USW00094728,20130213,67,6 46 | GHCND:USW00094728,20130214,78,6 47 | GHCND:USW00094728,20130215,128,28 48 | GHCND:USW00094728,20130216,50,-6 49 | GHCND:USW00094728,20130217,0,-78 50 | GHCND:USW00094728,20130218,17,-83 51 | GHCND:USW00094728,20130219,94,6 52 | GHCND:USW00094728,20130220,33,-39 53 | GHCND:USW00094728,20130221,11,-44 54 | GHCND:USW00094728,20130222,33,-39 55 | GHCND:USW00094728,20130223,56,22 56 | GHCND:USW00094728,20130224,83,11 57 | GHCND:USW00094728,20130225,72,0 58 | GHCND:USW00094728,20130226,67,17 59 | GHCND:USW00094728,20130227,83,22 60 | GHCND:USW00094728,20130228,106,39 61 | GHCND:USW00094728,20130301,72,22 62 | GHCND:USW00094728,20130302,44,-6 63 | GHCND:USW00094728,20130303,44,-17 64 | GHCND:USW00094728,20130304,56,-28 65 | GHCND:USW00094728,20130305,94,-6 66 | GHCND:USW00094728,20130306,56,33 67 | GHCND:USW00094728,20130307,33,6 68 | GHCND:USW00094728,20130308,56,-6 69 | GHCND:USW00094728,20130309,128,17 70 | GHCND:USW00094728,20130310,100,22 71 | GHCND:USW00094728,20130311,122,44 72 | GHCND:USW00094728,20130312,139,61 73 | GHCND:USW00094728,20130313,111,33 74 | GHCND:USW00094728,20130314,50,-17 75 | GHCND:USW00094728,20130315,83,-11 76 | GHCND:USW00094728,20130316,50,0 77 | GHCND:USW00094728,20130317,33,-17 78 | GHCND:USW00094728,20130318,17,-22 79 | GHCND:USW00094728,20130319,61,6 80 | GHCND:USW00094728,20130320,72,0 81 | GHCND:USW00094728,20130321,44,-11 82 | GHCND:USW00094728,20130322,50,-22 83 | GHCND:USW00094728,20130323,78,0 84 | GHCND:USW00094728,20130324,83,6 85 | GHCND:USW00094728,20130325,44,22 86 | GHCND:USW00094728,20130326,117,28 87 | GHCND:USW00094728,20130327,117,22 88 | GHCND:USW00094728,20130328,106,28 89 | GHCND:USW00094728,20130329,128,44 90 | GHCND:USW00094728,20130330,150,44 91 | GHCND:USW00094728,20130331,122,67 92 | GHCND:USW00094728,20130401,167,28 93 | GHCND:USW00094728,20130402,61,6 94 | GHCND:USW00094728,20130403,78,6 95 | GHCND:USW00094728,20130404,117,6 96 | GHCND:USW00094728,20130405,178,50 97 | GHCND:USW00094728,20130406,111,17 98 | GHCND:USW00094728,20130407,128,44 99 | GHCND:USW00094728,20130408,228,106 100 | GHCND:USW00094728,20130409,278,106 101 | GHCND:USW00094728,20130410,233,128 102 | GHCND:USW00094728,20130411,156,83 103 | GHCND:USW00094728,20130412,83,50 104 | GHCND:USW00094728,20130413,144,50 105 | GHCND:USW00094728,20130414,139,78 106 | GHCND:USW00094728,20130415,150,67 107 | GHCND:USW00094728,20130416,172,83 108 | GHCND:USW00094728,20130417,217,128 109 | GHCND:USW00094728,20130418,150,106 110 | GHCND:USW00094728,20130419,217,128 111 | GHCND:USW00094728,20130420,156,61 112 | GHCND:USW00094728,20130421,128,28 113 | GHCND:USW00094728,20130422,128,50 114 | GHCND:USW00094728,20130423,117,50 115 | GHCND:USW00094728,20130424,206,67 116 | GHCND:USW00094728,20130425,189,78 117 | GHCND:USW00094728,20130426,194,100 118 | GHCND:USW00094728,20130427,217,89 119 | GHCND:USW00094728,20130428,206,106 120 | GHCND:USW00094728,20130429,139,111 121 | GHCND:USW00094728,20130430,200,106 122 | GHCND:USW00094728,20130501,206,83 123 | GHCND:USW00094728,20130502,222,94 124 | GHCND:USW00094728,20130503,189,94 125 | GHCND:USW00094728,20130504,206,89 126 | GHCND:USW00094728,20130505,178,78 127 | GHCND:USW00094728,20130506,206,78 128 | GHCND:USW00094728,20130507,233,111 129 | GHCND:USW00094728,20130508,172,128 130 | GHCND:USW00094728,20130509,200,122 131 | GHCND:USW00094728,20130510,261,150 132 | GHCND:USW00094728,20130511,211,161 133 | GHCND:USW00094728,20130512,211,106 134 | GHCND:USW00094728,20130513,144,72 135 | GHCND:USW00094728,20130514,161,56 136 | GHCND:USW00094728,20130515,206,111 137 | GHCND:USW00094728,20130516,261,167 138 | GHCND:USW00094728,20130517,222,144 139 | GHCND:USW00094728,20130518,183,133 140 | GHCND:USW00094728,20130519,150,128 141 | GHCND:USW00094728,20130520,261,144 142 | GHCND:USW00094728,20130521,300,200 143 | GHCND:USW00094728,20130522,256,150 144 | GHCND:USW00094728,20130523,267,178 145 | GHCND:USW00094728,20130524,183,72 146 | GHCND:USW00094728,20130525,122,72 147 | GHCND:USW00094728,20130526,189,89 148 | GHCND:USW00094728,20130527,228,106 149 | GHCND:USW00094728,20130528,200,133 150 | GHCND:USW00094728,20130529,278,144 151 | GHCND:USW00094728,20130530,322,222 152 | GHCND:USW00094728,20130531,322,239 153 | GHCND:USW00094728,20130601,322,228 154 | GHCND:USW00094728,20130602,311,206 155 | GHCND:USW00094728,20130603,256,189 156 | GHCND:USW00094728,20130604,239,139 157 | GHCND:USW00094728,20130605,233,144 158 | GHCND:USW00094728,20130606,211,150 159 | GHCND:USW00094728,20130607,172,150 160 | GHCND:USW00094728,20130608,250,139 161 | GHCND:USW00094728,20130609,267,172 162 | GHCND:USW00094728,20130610,211,167 163 | GHCND:USW00094728,20130611,267,178 164 | GHCND:USW00094728,20130612,244,183 165 | GHCND:USW00094728,20130613,206,128 166 | GHCND:USW00094728,20130614,222,117 167 | GHCND:USW00094728,20130615,267,161 168 | GHCND:USW00094728,20130616,267,183 169 | GHCND:USW00094728,20130617,289,206 170 | GHCND:USW00094728,20130618,289,178 171 | GHCND:USW00094728,20130619,250,150 172 | GHCND:USW00094728,20130620,267,167 173 | GHCND:USW00094728,20130621,278,178 174 | GHCND:USW00094728,20130622,289,183 175 | GHCND:USW00094728,20130623,311,211 176 | GHCND:USW00094728,20130624,333,233 177 | GHCND:USW00094728,20130625,328,228 178 | GHCND:USW00094728,20130626,294,233 179 | GHCND:USW00094728,20130627,300,228 180 | GHCND:USW00094728,20130628,294,228 181 | GHCND:USW00094728,20130629,283,217 182 | GHCND:USW00094728,20130630,300,228 183 | GHCND:USW00094728,20130701,250,222 184 | GHCND:USW00094728,20130702,278,222 185 | GHCND:USW00094728,20130703,283,228 186 | GHCND:USW00094728,20130704,306,239 187 | GHCND:USW00094728,20130705,322,244 188 | GHCND:USW00094728,20130706,333,256 189 | GHCND:USW00094728,20130707,333,256 190 | GHCND:USW00094728,20130708,317,228 191 | GHCND:USW00094728,20130709,311,233 192 | GHCND:USW00094728,20130710,294,239 193 | GHCND:USW00094728,20130711,289,244 194 | GHCND:USW00094728,20130712,250,200 195 | GHCND:USW00094728,20130713,272,194 196 | GHCND:USW00094728,20130714,322,233 197 | GHCND:USW00094728,20130715,344,256 198 | GHCND:USW00094728,20130716,344,250 199 | GHCND:USW00094728,20130717,361,261 200 | GHCND:USW00094728,20130718,367,272 201 | GHCND:USW00094728,20130719,356,283 202 | GHCND:USW00094728,20130720,339,272 203 | GHCND:USW00094728,20130721,317,244 204 | GHCND:USW00094728,20130722,300,239 205 | GHCND:USW00094728,20130723,306,228 206 | GHCND:USW00094728,20130724,283,200 207 | GHCND:USW00094728,20130725,200,178 208 | GHCND:USW00094728,20130726,283,183 209 | GHCND:USW00094728,20130727,278,211 210 | GHCND:USW00094728,20130728,256,211 211 | GHCND:USW00094728,20130729,294,206 212 | GHCND:USW00094728,20130730,283,194 213 | GHCND:USW00094728,20130731,283,194 214 | GHCND:USW00094728,20130801,244,189 215 | GHCND:USW00094728,20130802,283,194 216 | GHCND:USW00094728,20130803,256,200 217 | GHCND:USW00094728,20130804,267,189 218 | GHCND:USW00094728,20130805,256,167 219 | GHCND:USW00094728,20130806,278,178 220 | GHCND:USW00094728,20130807,267,211 221 | GHCND:USW00094728,20130808,272,211 222 | GHCND:USW00094728,20130809,294,233 223 | GHCND:USW00094728,20130810,283,211 224 | GHCND:USW00094728,20130811,272,183 225 | GHCND:USW00094728,20130812,278,211 226 | GHCND:USW00094728,20130813,250,200 227 | GHCND:USW00094728,20130814,233,161 228 | GHCND:USW00094728,20130815,256,150 229 | GHCND:USW00094728,20130816,278,178 230 | GHCND:USW00094728,20130817,289,178 231 | GHCND:USW00094728,20130818,244,200 232 | GHCND:USW00094728,20130819,261,189 233 | GHCND:USW00094728,20130820,311,200 234 | GHCND:USW00094728,20130821,322,222 235 | GHCND:USW00094728,20130822,256,217 236 | GHCND:USW00094728,20130823,278,217 237 | GHCND:USW00094728,20130824,267,183 238 | GHCND:USW00094728,20130825,283,178 239 | GHCND:USW00094728,20130826,289,200 240 | GHCND:USW00094728,20130827,306,217 241 | GHCND:USW00094728,20130828,300,217 242 | GHCND:USW00094728,20130829,267,217 243 | GHCND:USW00094728,20130830,294,211 244 | GHCND:USW00094728,20130831,300,228 245 | GHCND:USW00094728,20130901,289,239 246 | GHCND:USW00094728,20130902,278,233 247 | GHCND:USW00094728,20130903,278,200 248 | GHCND:USW00094728,20130904,278,183 249 | GHCND:USW00094728,20130905,267,178 250 | GHCND:USW00094728,20130906,222,139 251 | GHCND:USW00094728,20130907,267,150 252 | GHCND:USW00094728,20130908,283,178 253 | GHCND:USW00094728,20130909,228,139 254 | GHCND:USW00094728,20130910,306,200 255 | GHCND:USW00094728,20130911,356,250 256 | GHCND:USW00094728,20130912,306,211 257 | GHCND:USW00094728,20130913,250,150 258 | GHCND:USW00094728,20130914,194,122 259 | GHCND:USW00094728,20130915,228,106 260 | GHCND:USW00094728,20130916,228,133 261 | GHCND:USW00094728,20130917,183,100 262 | GHCND:USW00094728,20130918,222,106 263 | GHCND:USW00094728,20130919,256,128 264 | GHCND:USW00094728,20130920,261,156 265 | GHCND:USW00094728,20130921,250,161 266 | GHCND:USW00094728,20130922,206,122 267 | GHCND:USW00094728,20130923,189,100 268 | GHCND:USW00094728,20130924,228,83 269 | GHCND:USW00094728,20130925,228,111 270 | GHCND:USW00094728,20130926,217,144 271 | GHCND:USW00094728,20130927,206,139 272 | GHCND:USW00094728,20130928,228,133 273 | GHCND:USW00094728,20130929,222,139 274 | GHCND:USW00094728,20130930,239,133 275 | GHCND:USW00094728,20131001,278,150 276 | GHCND:USW00094728,20131002,283,178 277 | GHCND:USW00094728,20131003,256,172 278 | GHCND:USW00094728,20131004,300,189 279 | GHCND:USW00094728,20131005,244,178 280 | GHCND:USW00094728,20131006,211,183 281 | GHCND:USW00094728,20131007,244,156 282 | GHCND:USW00094728,20131008,194,122 283 | GHCND:USW00094728,20131009,167,117 284 | GHCND:USW00094728,20131010,183,122 285 | GHCND:USW00094728,20131011,200,156 286 | GHCND:USW00094728,20131012,222,156 287 | GHCND:USW00094728,20131013,183,133 288 | GHCND:USW00094728,20131014,189,111 289 | GHCND:USW00094728,20131015,222,117 290 | GHCND:USW00094728,20131016,194,133 291 | GHCND:USW00094728,20131017,228,161 292 | GHCND:USW00094728,20131018,200,128 293 | GHCND:USW00094728,20131019,178,111 294 | GHCND:USW00094728,20131020,172,100 295 | GHCND:USW00094728,20131021,189,100 296 | GHCND:USW00094728,20131022,194,106 297 | GHCND:USW00094728,20131023,128,72 298 | GHCND:USW00094728,20131024,122,50 299 | GHCND:USW00094728,20131025,117,44 300 | GHCND:USW00094728,20131026,128,50 301 | GHCND:USW00094728,20131027,144,78 302 | GHCND:USW00094728,20131028,161,61 303 | GHCND:USW00094728,20131029,133,67 304 | GHCND:USW00094728,20131030,156,83 305 | GHCND:USW00094728,20131031,189,117 306 | GHCND:USW00094728,20131101,211,150 307 | GHCND:USW00094728,20131102,200,128 308 | GHCND:USW00094728,20131103,128,28 309 | GHCND:USW00094728,20131104,78,17 310 | GHCND:USW00094728,20131105,128,50 311 | GHCND:USW00094728,20131106,161,94 312 | GHCND:USW00094728,20131107,178,67 313 | GHCND:USW00094728,20131108,100,44 314 | GHCND:USW00094728,20131109,100,33 315 | GHCND:USW00094728,20131110,161,67 316 | GHCND:USW00094728,20131111,117,61 317 | GHCND:USW00094728,20131112,111,-5 318 | GHCND:USW00094728,20131113,39,-16 319 | GHCND:USW00094728,20131114,111,6 320 | GHCND:USW00094728,20131115,139,67 321 | GHCND:USW00094728,20131116,156,72 322 | GHCND:USW00094728,20131117,156,106 323 | GHCND:USW00094728,20131118,183,106 324 | GHCND:USW00094728,20131119,106,22 325 | GHCND:USW00094728,20131120,67,0 326 | GHCND:USW00094728,20131121,111,17 327 | GHCND:USW00094728,20131122,139,106 328 | GHCND:USW00094728,20131123,122,-5 329 | GHCND:USW00094728,20131124,-10,-49 330 | GHCND:USW00094728,20131125,17,-49 331 | GHCND:USW00094728,20131126,83,6 332 | GHCND:USW00094728,20131127,167,17 333 | GHCND:USW00094728,20131128,17,-10 334 | GHCND:USW00094728,20131129,39,-16 335 | GHCND:USW00094728,20131130,39,-38 336 | GHCND:USW00094728,20131201,94,22 337 | GHCND:USW00094728,20131202,94,50 338 | GHCND:USW00094728,20131203,117,33 339 | GHCND:USW00094728,20131204,111,50 340 | GHCND:USW00094728,20131205,156,89 341 | GHCND:USW00094728,20131206,167,28 342 | GHCND:USW00094728,20131207,50,0 343 | GHCND:USW00094728,20131208,6,-16 344 | GHCND:USW00094728,20131209,39,-5 345 | GHCND:USW00094728,20131210,28,-10 346 | GHCND:USW00094728,20131211,6,-27 347 | GHCND:USW00094728,20131212,-10,-49 348 | GHCND:USW00094728,20131213,17,-49 349 | GHCND:USW00094728,20131214,11,-55 350 | GHCND:USW00094728,20131215,44,-10 351 | GHCND:USW00094728,20131216,6,-38 352 | GHCND:USW00094728,20131217,0,-43 353 | GHCND:USW00094728,20131218,28,-49 354 | GHCND:USW00094728,20131219,83,-10 355 | GHCND:USW00094728,20131220,117,50 356 | GHCND:USW00094728,20131221,183,106 357 | GHCND:USW00094728,20131222,217,161 358 | GHCND:USW00094728,20131223,178,56 359 | GHCND:USW00094728,20131224,56,-32 360 | GHCND:USW00094728,20131225,-5,-71 361 | GHCND:USW00094728,20131226,22,-10 362 | GHCND:USW00094728,20131227,44,-5 363 | GHCND:USW00094728,20131228,128,22 364 | GHCND:USW00094728,20131229,89,50 365 | GHCND:USW00094728,20131230,72,-49 366 | GHCND:USW00094728,20131231,0,-60 367 | GHCND:USW00094728,20140101,6,-43 368 | -------------------------------------------------------------------------------- /template/Plantilla.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\"AeroPython\"" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Clase 3b: Título de la clase" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "_Aquí una introducción en cursiva y te cuento lo que vamos a hacer_" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "## Sección 1" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "Aquí empiezo a explicar" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 1, 41 | "metadata": { 42 | "collapsed": false 43 | }, 44 | "outputs": [], 45 | "source": [ 46 | "#Aquí el código\n", 47 | "import numpy as np\n", 48 | "%matplotlib inline\n", 49 | "import matplotlib.pyplot as plt" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "### Subsección 1.1" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "#### Subsubsección 1.1.1" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "##### Ejercicio" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "---" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": {}, 83 | "source": [ 84 | "_Aquí un resumen de la clase con lo que hemos aprendido y algunos links_" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "Si te ha gustado esta clase:\n", 92 | "\n", 93 | "Tweet\n", 94 | "\n", 95 | "\n", 96 | "---" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": {}, 102 | "source": [ 103 | "###### \"AeroPython\" Curso impartido por: [Juan Luis Cano](http://es.linkedin.com/in/juanluiscanor) & [Álex Sáez](http://es.linkedin.com/pub/alejandro-saez-mollejo/55/22/473)" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "###### En colaboración: Alberto Lorenzo" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "####

¡Síguenos en Twitter!" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": {}, 123 | "source": [ 124 | "###### Follow @Pybonacci Follow @Alex__S12 Follow @newlawrence " 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "##### \"Licencia
Curso AeroPython por Juan Luis Cano Rodriguez y Alejandro Sáez Mollejo se distribuye bajo una Licencia Creative Commons Atribución 4.0 Internacional." 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": {}, 137 | "source": [ 138 | "##### " 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "---\n", 146 | "_Las siguientes celdas contienen configuración del Notebook_\n", 147 | "\n", 148 | "_Para visualizar y utlizar los enlaces a Twitter el notebook debe ejecutarse como [seguro](http://ipython.org/ipython-doc/dev/notebook/security.html)_\n", 149 | "\n", 150 | " File > Trusted Notebook" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 2, 156 | "metadata": { 157 | "collapsed": false 158 | }, 159 | "outputs": [ 160 | { 161 | "data": { 162 | "text/html": [ 163 | "Follow @Pybonacci\n", 164 | "" 165 | ], 166 | "text/plain": [ 167 | "" 168 | ] 169 | }, 170 | "metadata": {}, 171 | "output_type": "display_data" 172 | } 173 | ], 174 | "source": [ 175 | "%%html\n", 176 | "Follow @Pybonacci\n", 177 | "" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 5, 183 | "metadata": { 184 | "collapsed": false 185 | }, 186 | "outputs": [ 187 | { 188 | "data": { 189 | "text/html": [ 190 | "/* This template is inspired in the one used by Lorena Barba\n", 191 | "in the numerical-mooc repository: https://github.com/numerical-mooc/numerical-mooc\n", 192 | "We thank her work and hope you also enjoy the look of the notobooks with this style */\n", 193 | "\n", 194 | "\n", 195 | "\n", 196 | "El estilo se ha aplicado =)\n", 197 | "\n", 198 | "\n", 335 | "\n" 351 | ], 352 | "text/plain": [ 353 | "" 354 | ] 355 | }, 356 | "execution_count": 5, 357 | "metadata": {}, 358 | "output_type": "execute_result" 359 | } 360 | ], 361 | "source": [ 362 | "# Esta celda da el estilo al notebook\n", 363 | "from IPython.core.display import HTML\n", 364 | "css_file = '../static/styles/style.css'\n", 365 | "HTML(open(css_file, \"r\").read())" 366 | ] 367 | } 368 | ], 369 | "metadata": { 370 | "kernelspec": { 371 | "display_name": "Python 3", 372 | "language": "python", 373 | "name": "python3" 374 | }, 375 | "language_info": { 376 | "codemirror_mode": { 377 | "name": "ipython", 378 | "version": 3 379 | }, 380 | "file_extension": ".py", 381 | "mimetype": "text/x-python", 382 | "name": "python", 383 | "nbconvert_exporter": "python", 384 | "pygments_lexer": "ipython3", 385 | "version": "3.4.3" 386 | } 387 | }, 388 | "nbformat": 4, 389 | "nbformat_minor": 0 390 | } 391 | -------------------------------------------------------------------------------- /static/jdcal.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | """Functions for converting between Julian dates and calendar dates. 3 | 4 | A function for converting Gregorian calendar dates to Julian dates, and 5 | another function for converting Julian calendar dates to Julian dates 6 | are defined. Two functions for the reverse calculations are also 7 | defined. 8 | 9 | Different regions of the world switched to Gregorian calendar from 10 | Julian calendar on different dates. Having separate functions for Julian 11 | and Gregorian calendars allow maximum flexibility in choosing the 12 | relevant calendar. 13 | 14 | All the above functions are "proleptic". This means that they work for 15 | dates on which the concerned calendar is not valid. For example, 16 | Gregorian calendar was not used prior to around October 1582. 17 | 18 | Julian dates are stored in two floating point numbers (double). Julian 19 | dates, and Modified Julian dates, are large numbers. If only one number 20 | is used, then the precision of the time stored is limited. Using two 21 | numbers, time can be split in a manner that will allow maximum 22 | precision. For example, the first number could be the Julian date for 23 | the beginning of a day and the second number could be the fractional 24 | day. Calculations that need the latter part can now work with maximum 25 | precision. 26 | 27 | A function to test if a given Gregorian calendar year is a leap year is 28 | defined. 29 | 30 | Zero point of Modified Julian Date (MJD) and the MJD of 2000/1/1 31 | 12:00:00 are also given. 32 | 33 | This module is based on the TPM C library, by Jeffery W. Percival. The 34 | idea for splitting Julian date into two floating point numbers was 35 | inspired by the IAU SOFA C library. 36 | 37 | :author: Prasanth Nair 38 | :contact: prasanthhn@gmail.com 39 | :license: BSD (http://www.opensource.org/licenses/bsd-license.php) 40 | """ 41 | from __future__ import division 42 | from __future__ import print_function 43 | import math 44 | 45 | __version__ = "1.0" 46 | 47 | MJD_0 = 2400000.5 48 | MJD_JD2000 = 51544.5 49 | 50 | 51 | def fpart(x): 52 | """Return fractional part of given number.""" 53 | return math.modf(x)[0] 54 | 55 | 56 | def ipart(x): 57 | """Return integer part of given number.""" 58 | return math.modf(x)[1] 59 | 60 | 61 | def is_leap(year): 62 | """Leap year or not in the Gregorian calendar.""" 63 | x = math.fmod(year, 4) 64 | y = math.fmod(year, 100) 65 | z = math.fmod(year, 400) 66 | 67 | # Divisible by 4 and, 68 | # either not divisible by 100 or divisible by 400. 69 | return not x and (y or not z) 70 | 71 | 72 | def gcal2jd(year, month, day): 73 | """Gregorian calendar date to Julian date. 74 | 75 | The input and output are for the proleptic Gregorian calendar, 76 | i.e., no consideration of historical usage of the calendar is 77 | made. 78 | 79 | Parameters 80 | ---------- 81 | year : int 82 | Year as an integer. 83 | month : int 84 | Month as an integer. 85 | day : int 86 | Day as an integer. 87 | 88 | Returns 89 | ------- 90 | jd1, jd2: 2-element tuple of floats 91 | When added together, the numbers give the Julian date for the 92 | given Gregorian calendar date. The first number is always 93 | MJD_0 i.e., 2451545.5. So the second is the MJD. 94 | 95 | Examples 96 | -------- 97 | >>> gcal2jd(2000,1,1) 98 | (2400000.5, 51544.0) 99 | >>> 2400000.5 + 51544.0 + 0.5 100 | 2451545.0 101 | >>> year = [-4699, -2114, -1050, -123, -1, 0, 1, 123, 1678.0, 2000, 102 | ....: 2012, 2245] 103 | >>> month = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 104 | >>> day = [1, 12, 23, 14, 25, 16, 27, 8, 9, 10, 11, 31] 105 | >>> x = [gcal2jd(y, m, d) for y, m, d in zip(year, month, day)] 106 | >>> for i in x: print i 107 | (2400000.5, -2395215.0) 108 | (2400000.5, -1451021.0) 109 | (2400000.5, -1062364.0) 110 | (2400000.5, -723762.0) 111 | (2400000.5, -679162.0) 112 | (2400000.5, -678774.0) 113 | (2400000.5, -678368.0) 114 | (2400000.5, -633797.0) 115 | (2400000.5, -65812.0) 116 | (2400000.5, 51827.0) 117 | (2400000.5, 56242.0) 118 | (2400000.5, 141393.0) 119 | 120 | Negative months and days are valid. For example, 2000/-2/-4 => 121 | 1999/+12-2/-4 => 1999/10/-4 => 1999/9/30-4 => 1999/9/26. 122 | 123 | >>> gcal2jd(2000, -2, -4) 124 | (2400000.5, 51447.0) 125 | >>> gcal2jd(1999, 9, 26) 126 | (2400000.5, 51447.0) 127 | 128 | >>> gcal2jd(2000, 2, -1) 129 | (2400000.5, 51573.0) 130 | >>> gcal2jd(2000, 1, 30) 131 | (2400000.5, 51573.0) 132 | 133 | >>> gcal2jd(2000, 3, -1) 134 | (2400000.5, 51602.0) 135 | >>> gcal2jd(2000, 2, 28) 136 | (2400000.5, 51602.0) 137 | 138 | Month 0 becomes previous month. 139 | 140 | >>> gcal2jd(2000, 0, 1) 141 | (2400000.5, 51513.0) 142 | >>> gcal2jd(1999, 12, 1) 143 | (2400000.5, 51513.0) 144 | 145 | Day number 0 becomes last day of previous month. 146 | 147 | >>> gcal2jd(2000, 3, 0) 148 | (2400000.5, 51603.0) 149 | >>> gcal2jd(2000, 2, 29) 150 | (2400000.5, 51603.0) 151 | 152 | If `day` is greater than the number of days in `month`, then it 153 | gets carried over to the next month. 154 | 155 | >>> gcal2jd(2000,2,30) 156 | (2400000.5, 51604.0) 157 | >>> gcal2jd(2000,3,1) 158 | (2400000.5, 51604.0) 159 | 160 | >>> gcal2jd(2001,2,30) 161 | (2400000.5, 51970.0) 162 | >>> gcal2jd(2001,3,2) 163 | (2400000.5, 51970.0) 164 | 165 | Notes 166 | ----- 167 | The returned Julian date is for mid-night of the given date. To 168 | find the Julian date for any time of the day, simply add time as a 169 | fraction of a day. For example Julian date for mid-day can be 170 | obtained by adding 0.5 to either the first part or the second 171 | part. The latter is preferable, since it will give the MJD for the 172 | date and time. 173 | 174 | BC dates should be given as -(BC - 1) where BC is the year. For 175 | example 1 BC == 0, 2 BC == -1, and so on. 176 | 177 | Negative numbers can be used for `month` and `day`. For example 178 | 2000, -1, 1 is the same as 1999, 11, 1. 179 | 180 | The Julian dates are proleptic Julian dates, i.e., values are 181 | returned without considering if Gregorian dates are valid for the 182 | given date. 183 | 184 | The input values are truncated to integers. 185 | 186 | """ 187 | year = int(year) 188 | month = int(month) 189 | day = int(day) 190 | 191 | a = ipart((month - 14) / 12.0) 192 | jd = ipart((1461 * (year + 4800 + a)) / 4.0) 193 | jd += ipart((367 * (month - 2 - 12 * a)) / 12.0) 194 | x = ipart((year + 4900 + a) / 100.0) 195 | jd -= ipart((3 * x) / 4.0) 196 | jd += day - 2432075.5 # was 32075; add 2400000.5 197 | 198 | jd -= 0.5 # 0 hours; above JD is for midday, switch to midnight. 199 | 200 | return MJD_0, jd 201 | 202 | 203 | def jd2gcal(jd1, jd2): 204 | """Julian date to Gregorian calendar date and time of day. 205 | 206 | The input and output are for the proleptic Gregorian calendar, 207 | i.e., no consideration of historical usage of the calendar is 208 | made. 209 | 210 | Parameters 211 | ---------- 212 | jd1, jd2: int 213 | Sum of the two numbers is taken as the given Julian date. For 214 | example `jd1` can be the zero point of MJD (MJD_0) and `jd2` 215 | can be the MJD of the date and time. But any combination will 216 | work. 217 | 218 | Returns 219 | ------- 220 | y, m, d, f : int, int, int, float 221 | Four element tuple containing year, month, day and the 222 | fractional part of the day in the Gregorian calendar. The first 223 | three are integers, and the last part is a float. 224 | 225 | Examples 226 | -------- 227 | >>> jd2gcal(*gcal2jd(2000,1,1)) 228 | (2000, 1, 1, 0.0) 229 | >>> jd2gcal(*gcal2jd(1950,1,1)) 230 | (1950, 1, 1, 0.0) 231 | 232 | Out of range months and days are carried over to the next/previous 233 | year or next/previous month. See gcal2jd for more examples. 234 | 235 | >>> jd2gcal(*gcal2jd(1999,10,12)) 236 | (1999, 10, 12, 0.0) 237 | >>> jd2gcal(*gcal2jd(2000,2,30)) 238 | (2000, 3, 1, 0.0) 239 | >>> jd2gcal(*gcal2jd(-1999,10,12)) 240 | (-1999, 10, 12, 0.0) 241 | >>> jd2gcal(*gcal2jd(2000, -2, -4)) 242 | (1999, 9, 26, 0.0) 243 | 244 | >>> gcal2jd(2000,1,1) 245 | (2400000.5, 51544.0) 246 | >>> jd2gcal(2400000.5, 51544.0) 247 | (2000, 1, 1, 0.0) 248 | >>> jd2gcal(2400000.5, 51544.5) 249 | (2000, 1, 1, 0.5) 250 | >>> jd2gcal(2400000.5, 51544.245) 251 | (2000, 1, 1, 0.24500000000261934) 252 | >>> jd2gcal(2400000.5, 51544.1) 253 | (2000, 1, 1, 0.099999999998544808) 254 | >>> jd2gcal(2400000.5, 51544.75) 255 | (2000, 1, 1, 0.75) 256 | 257 | Notes 258 | ----- 259 | The last element of the tuple is the same as 260 | 261 | (hh + mm / 60.0 + ss / 3600.0) / 24.0 262 | 263 | where hh, mm, and ss are the hour, minute and second of the day. 264 | 265 | See Also 266 | -------- 267 | gcal2jd 268 | 269 | """ 270 | from math import modf 271 | 272 | jd1_f, jd1_i = modf(jd1) 273 | jd2_f, jd2_i = modf(jd2) 274 | 275 | jd_i = jd1_i + jd2_i 276 | 277 | f = jd1_f + jd2_f 278 | 279 | # Set JD to noon of the current date. Fractional part is the 280 | # fraction from midnight of the current date. 281 | if -0.5 < f < 0.5: 282 | f += 0.5 283 | elif f >= 0.5: 284 | jd_i += 1 285 | f -= 0.5 286 | elif f <= -0.5: 287 | jd_i -= 1 288 | f += 1.5 289 | 290 | l = jd_i + 68569 291 | n = ipart((4 * l) / 146097.0) 292 | l -= ipart(((146097 * n) + 3) / 4.0) 293 | i = ipart((4000 * (l + 1)) / 1461001) 294 | l -= ipart((1461 * i) / 4.0) - 31 295 | j = ipart((80 * l) / 2447.0) 296 | day = l - ipart((2447 * j) / 80.0) 297 | l = ipart(j / 11.0) 298 | month = j + 2 - (12 * l) 299 | year = 100 * (n - 49) + i + l 300 | 301 | return int(year), int(month), int(day), f 302 | 303 | 304 | def jcal2jd(year, month, day): 305 | """Julian calendar date to Julian date. 306 | 307 | The input and output are for the proleptic Julian calendar, 308 | i.e., no consideration of historical usage of the calendar is 309 | made. 310 | 311 | Parameters 312 | ---------- 313 | year : int 314 | Year as an integer. 315 | month : int 316 | Month as an integer. 317 | day : int 318 | Day as an integer. 319 | 320 | Returns 321 | ------- 322 | jd1, jd2: 2-element tuple of floats 323 | When added together, the numbers give the Julian date for the 324 | given Julian calendar date. The first number is always 325 | MJD_0 i.e., 2451545.5. So the second is the MJD. 326 | 327 | Examples 328 | -------- 329 | >>> jcal2jd(2000, 1, 1) 330 | (2400000.5, 51557.0) 331 | >>> year = [-4699, -2114, -1050, -123, -1, 0, 1, 123, 1678, 2000, 332 | ...: 2012, 2245] 333 | >>> month = [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12] 334 | >>> day = [1, 12, 23, 14, 25, 16, 27, 8, 9, 10, 11, 31] 335 | >>> x = [jcal2jd(y, m, d) for y, m, d in zip(year, month, day)] 336 | >>> for i in x: print i 337 | (2400000.5, -2395252.0) 338 | (2400000.5, -1451039.0) 339 | (2400000.5, -1062374.0) 340 | (2400000.5, -723765.0) 341 | (2400000.5, -679164.0) 342 | (2400000.5, -678776.0) 343 | (2400000.5, -678370.0) 344 | (2400000.5, -633798.0) 345 | (2400000.5, -65772.0) 346 | (2400000.5, 51871.0) 347 | (2400000.5, 56285.0) 348 | 349 | Notes 350 | ----- 351 | Unlike `gcal2jd`, negative months and days can result in incorrect 352 | Julian dates. 353 | 354 | """ 355 | year = int(year) 356 | month = int(month) 357 | day = int(day) 358 | 359 | jd = 367 * year 360 | x = ipart((month - 9) / 7.0) 361 | jd -= ipart((7 * (year + 5001 + x)) / 4.0) 362 | jd += ipart((275 * month) / 9.0) 363 | jd += day 364 | jd += 1729777 - 2400000.5 # Return 240000.5 as first part of JD. 365 | 366 | jd -= 0.5 # Convert midday to midnight. 367 | 368 | return MJD_0, jd 369 | 370 | 371 | def jd2jcal(jd1, jd2): 372 | """Julian calendar date for the given Julian date. 373 | 374 | The input and output are for the proleptic Julian calendar, 375 | i.e., no consideration of historical usage of the calendar is 376 | made. 377 | 378 | Parameters 379 | ---------- 380 | jd1, jd2: int 381 | Sum of the two numbers is taken as the given Julian date. For 382 | example `jd1` can be the zero point of MJD (MJD_0) and `jd2` 383 | can be the MJD of the date and time. But any combination will 384 | work. 385 | 386 | Returns 387 | ------- 388 | y, m, d, f : int, int, int, float 389 | Four element tuple containing year, month, day and the 390 | fractional part of the day in the Julian calendar. The first 391 | three are integers, and the last part is a float. 392 | 393 | Examples 394 | -------- 395 | >>> jd2jcal(*jcal2jd(2000, 1, 1)) 396 | (2000, 1, 1, 0.0) 397 | >>> jd2jcal(*jcal2jd(-4000, 10, 11)) 398 | (-4000, 10, 11, 0.0) 399 | 400 | >>> jcal2jd(2000, 1, 1) 401 | (2400000.5, 51557.0) 402 | >>> jd2jcal(2400000.5, 51557.0) 403 | (2000, 1, 1, 0.0) 404 | >>> jd2jcal(2400000.5, 51557.5) 405 | (2000, 1, 1, 0.5) 406 | >>> jd2jcal(2400000.5, 51557.245) 407 | (2000, 1, 1, 0.24500000000261934) 408 | >>> jd2jcal(2400000.5, 51557.1) 409 | (2000, 1, 1, 0.099999999998544808) 410 | >>> jd2jcal(2400000.5, 51557.75) 411 | (2000, 1, 1, 0.75) 412 | 413 | """ 414 | from math import modf 415 | 416 | jd1_f, jd1_i = modf(jd1) 417 | jd2_f, jd2_i = modf(jd2) 418 | 419 | jd_i = jd1_i + jd2_i 420 | 421 | f = jd1_f + jd2_f 422 | 423 | # Set JD to noon of the current date. Fractional part is the 424 | # fraction from midnight of the current date. 425 | if -0.5 < f < 0.5: 426 | f += 0.5 427 | elif f >= 0.5: 428 | jd_i += 1 429 | f -= 0.5 430 | elif f <= -0.5: 431 | jd_i -= 1 432 | f += 1.5 433 | 434 | j = jd_i + 1402.0 435 | k = ipart((j - 1) / 1461.0) 436 | l = j - (1461.0 * k) 437 | n = ipart((l - 1) / 365.0) - ipart(l / 1461.0) 438 | i = l - (365.0 * n) + 30.0 439 | j = ipart((80.0 * i) / 2447.0) 440 | day = i - ipart((2447.0 * j) / 80.0) 441 | i = ipart(j / 11.0) 442 | month = j + 2 - (12.0 * i) 443 | year = (4 * k) + n + i - 4716.0 444 | 445 | return int(year), int(month), int(day), f 446 | 447 | 448 | # Some tests. 449 | def _test_gcal2jd_with_sla_cldj(): 450 | """Compare gcal2jd with slalib.sla_cldj.""" 451 | import random 452 | try: 453 | from pyslalib import slalib 454 | except ImportError: 455 | print("SLALIB (PySLALIB not available).") 456 | return 1 457 | n = 1000 458 | mday = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 459 | 460 | # sla_cldj needs year > -4699 i.e., 4700 BC. 461 | year = [random.randint(-4699, 2200) for i in range(n)] 462 | month = [random.randint(1, 12) for i in range(n)] 463 | day = [random.randint(1, 31) for i in range(n)] 464 | for i in range(n): 465 | x = 0 466 | if is_leap(year[i]) and month[i] == 2: 467 | x = 1 468 | if day[i] > mday[month[i]] + x: 469 | day[i] = mday[month[i]] 470 | 471 | jd_jdc = [gcal2jd(y, m, d)[1] 472 | for y, m, d in zip(year, month, day)] 473 | jd_sla = [slalib.sla_cldj(y, m, d)[0] 474 | for y, m, d in zip(year, month, day)] 475 | diff = [abs(i - j) for i, j in zip(jd_sla, jd_jdc)] 476 | assert max(diff) <= 1e-8 477 | assert min(diff) <= 1e-8 478 | 479 | 480 | def _test_jd2gcal(): 481 | """Check jd2gcal as reverse of gcal2jd.""" 482 | import random 483 | n = 1000 484 | mday = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 485 | 486 | year = [random.randint(-4699, 2200) for i in range(n)] 487 | month = [random.randint(1, 12) for i in range(n)] 488 | day = [random.randint(1, 31) for i in range(n)] 489 | for i in range(n): 490 | x = 0 491 | if is_leap(year[i]) and month[i] == 2: 492 | x = 1 493 | if day[i] > mday[month[i]] + x: 494 | day[i] = mday[month[i]] 495 | 496 | jd = [gcal2jd(y, m, d)[1] 497 | for y, m, d in zip(year, month, day)] 498 | 499 | x = [jd2gcal(MJD_0, i) for i in jd] 500 | 501 | for i in range(n): 502 | assert x[i][0] == year[i] 503 | assert x[i][1] == month[i] 504 | assert x[i][2] == day[i] 505 | assert x[i][3] <= 1e-15 506 | 507 | 508 | def _test_jd2jcal(): 509 | """Check jd2jcal as reverse of jcal2jd.""" 510 | import random 511 | n = 1000 512 | year = [random.randint(-4699, 2200) for i in range(n)] 513 | month = [random.randint(1, 12) for i in range(n)] 514 | day = [random.randint(1, 28) for i in range(n)] 515 | 516 | jd = [jcal2jd(y, m, d)[1] 517 | for y, m, d in zip(year, month, day)] 518 | 519 | x = [jd2gcal(MJD_0, i) for i in jd] 520 | 521 | for i in range(n): 522 | assert x[i][0] == year[i] 523 | assert x[i][1] == month[i] 524 | assert x[i][2] == day[i] 525 | assert x[i][3] <= 1e-15 526 | -------------------------------------------------------------------------------- /notebooks_vacios/Clase1b_Ejercicios.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\"AeroPython\"" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Clase 1b: Ejercicios prácticos" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "_En esta clase vamos a afianzar los conocimientos de Python que acabamos de adquirir haciendo algunos ejercicios, y así retener las peculiaridades de la sintaxis y aclarar algunos detalles a tener en cuenta cuando se trabaja en modo interactivo._" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "## Funciones" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "Lo más importante para programar, y no solo en Python, es saber organizar el código en piezas más pequeñas que hagan tareas independientes y combinarlas entre sí. Las **funciones** son el primer nivel de organización del código: reciben unas *entradas*, las *procesan* y devuelven unas *salidas*." 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "![Black box](../static/blackbox.jpg)" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "1. Ejercicio: Función de una entrada: si un número es mayor o menor que cinco\n", 50 | "2. Ejercicio: Función para hallar la suma de los $n$ primeros números [Prueba unitaria]\n", 51 | "3. Ejercicio: Función que suma los $n$ primeros números hasta un tope [Bucles]\n", 52 | "4. Ejercicio: f(tiempo_examen, descanso) -> cumple la normativa o no\n", 53 | "5. Ejercicio: raíces cuadradas por el método de Newton (comparar con np.sqrt)\n", 54 | "6. Ejercicio: $n$ primeros números de la sucesión de Fibonacci" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "### Ejercicio 4\n", 62 | "\n", 63 | "La normativa de exámenes es: *\"si un examen dura más de 3 horas, entonces debe tener un descanso\"*. Los argumentos de la función son el tiempo en horas y un valor `True` o `False` que indica si hay descanso o no." 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "### Ejercicio 5" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "Hallar $x = \\sqrt{S}$.\n", 78 | "\n", 79 | "1. $\\displaystyle \\tilde{x} \\leftarrow \\frac{S}{2}$.\n", 80 | "2. $\\displaystyle \\tilde{x} \\leftarrow \\frac{1}{2}\\left(\\tilde{x} + \\frac{S}{\\tilde{x}}\\right)$.\n", 81 | "3. Repetir (2) hasta que se alcance un límite de iteraciones o un criterio de convergencia." 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "### Ejercicio 6" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "Secuencia de Fibonacci: $F_n = F_{n - 1} + F_{n - 2}$, con $F_0 = 0$ y $F_1 = 1$.\n", 96 | "\n", 97 | "$$0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...$$" 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "Con recursión:" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 62, 110 | "metadata": { 111 | "collapsed": false 112 | }, 113 | "outputs": [], 114 | "source": [] 115 | }, 116 | { 117 | "cell_type": "markdown", 118 | "metadata": {}, 119 | "source": [ 120 | "Con iteración:" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 65, 126 | "metadata": { 127 | "collapsed": false 128 | }, 129 | "outputs": [], 130 | "source": [] 131 | }, 132 | { 133 | "cell_type": "markdown", 134 | "metadata": {}, 135 | "source": [ 136 | "Imprimir una lista con los $n$ primeros:" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 70, 142 | "metadata": { 143 | "collapsed": false 144 | }, 145 | "outputs": [], 146 | "source": [] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 71, 151 | "metadata": { 152 | "collapsed": false 153 | }, 154 | "outputs": [ 155 | { 156 | "data": { 157 | "text/plain": [ 158 | "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]" 159 | ] 160 | }, 161 | "execution_count": 71, 162 | "metadata": {}, 163 | "output_type": "execute_result" 164 | } 165 | ], 166 | "source": [] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "---" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "_En esta clase hemos visto cómo crear funciones que encapsulen tareas de nuestro programa y las hemos aplicado para respondernos ciertas preguntas sencillas._\n", 180 | "\n", 181 | "**Referencias**\n", 182 | "\n", 183 | "* Libro \"Learn Python the Hard Way\" http://learnpythonthehardway.org/book/\n", 184 | "* Python Tutor, para visualizar código Python paso a paso http://pythontutor.com/\n", 185 | "* Libro \"How To Think Like a Computer Scientist\" http://interactivepython.org/runestone/static/thinkcspy/toc.html\n", 186 | "* Project Euler: ejercicios para aprender Python https://projecteuler.net/problems\n", 187 | "* Python Challenge (!) http://www.pythonchallenge.com/" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": {}, 193 | "source": [ 194 | "Si te ha gustado esta clase:\n", 195 | "\n", 196 | "Tweet\n", 197 | "\n", 198 | "\n", 199 | "---" 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": {}, 205 | "source": [ 206 | "####

¡Síguenos en Twitter!" 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "metadata": {}, 212 | "source": [ 213 | "###### Follow @AeroPython " 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": {}, 219 | "source": [ 220 | "##### \"Licencia
Curso AeroPython por Juan Luis Cano Rodriguez y Alejandro Sáez Mollejo se distribuye bajo una Licencia Creative Commons Atribución 4.0 Internacional." 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": {}, 226 | "source": [ 227 | "##### " 228 | ] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "metadata": {}, 233 | "source": [ 234 | "---\n", 235 | "_Las siguientes celdas contienen configuración del Notebook_\n", 236 | "\n", 237 | "_Para visualizar y utlizar los enlaces a Twitter el notebook debe ejecutarse como [seguro](http://ipython.org/ipython-doc/dev/notebook/security.html)_\n", 238 | "\n", 239 | " File > Trusted Notebook" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 2, 245 | "metadata": { 246 | "collapsed": false 247 | }, 248 | "outputs": [ 249 | { 250 | "data": { 251 | "text/html": [ 252 | "Follow @AeroPython\n", 253 | "" 254 | ], 255 | "text/plain": [ 256 | "" 257 | ] 258 | }, 259 | "metadata": {}, 260 | "output_type": "display_data" 261 | } 262 | ], 263 | "source": [ 264 | "%%html\n", 265 | "Follow @AeroPython\n", 266 | "" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": 1, 272 | "metadata": { 273 | "collapsed": false 274 | }, 275 | "outputs": [ 276 | { 277 | "data": { 278 | "text/html": [ 279 | "\n", 280 | "\n", 281 | "El estilo se ha aplicado =)\n", 282 | "\n", 283 | "\n", 420 | "\n" 436 | ], 437 | "text/plain": [ 438 | "" 439 | ] 440 | }, 441 | "execution_count": 1, 442 | "metadata": {}, 443 | "output_type": "execute_result" 444 | } 445 | ], 446 | "source": [ 447 | "# Esta celda da el estilo al notebook\n", 448 | "from IPython.core.display import HTML\n", 449 | "css_file = '../static/styles/style.css'\n", 450 | "HTML(open(css_file, \"r\").read())" 451 | ] 452 | } 453 | ], 454 | "metadata": { 455 | "kernelspec": { 456 | "display_name": "Python 3", 457 | "language": "python", 458 | "name": "python3" 459 | }, 460 | "language_info": { 461 | "codemirror_mode": { 462 | "name": "ipython", 463 | "version": 3 464 | }, 465 | "file_extension": ".py", 466 | "mimetype": "text/x-python", 467 | "name": "python", 468 | "nbconvert_exporter": "python", 469 | "pygments_lexer": "ipython3", 470 | "version": "3.4.3" 471 | } 472 | }, 473 | "nbformat": 4, 474 | "nbformat_minor": 0 475 | } 476 | -------------------------------------------------------------------------------- /notebooks_completos/Clase0_Bienvenido.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\"AeroPython\"" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Bienvenido al curso de #AeroPython" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "Como habrás podido observar en el [repositorio de GitHub](https://github.com/AeroPython/Curso-AeroPython-UC3M), dispones de todo el material que utilizamos durante los cursos para poder __iniciarte desde cero en la programación en Python.__ __Esta guía te indicará los pasos a seguir para que te instales Python, descargues el material y puedas aprender a tu ritmo.__" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "__Nuestra herramienta fundamental de trabajo es el Notebook de IPython__, podrás conocer más acerca de él en la _[Clase1a](http://nbviewer.ipython.org/github/AeroPython/Curso-AeroPython-UC3M/blob/master/notebooks_completos/Clase1a_Intro-Python-IPython.ipynb)_. Durante el curso te familiarizarás con él y aprenderás a manejarlo (este documento ha sido generado a partir de un notebook)." 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "## Pasos a seguir:" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "### 1. Descarga." 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "La instalación de Python, el Notebook y todos los paquetes que utilizaremos, por separado puede ser una tarea ardua y agotadora, pero no te preocupes: ¡alguien ha hecho ya el trabajo duro!\n", 50 | "\n", 51 | "__[Anaconda](https://continuum.io/anaconda/) es una distribución de Python que recopila muchas de las bibliotecas necesarias en el ámbito de la computación científica__ y desde luego, todas las que necesitaremos en este curso. Además __incluye herramientas para programar en Python, como el Notebook y [Spyder](https://code.google.com/p/spyderlib/)__ (un IDE al estilo de MATLAB)." 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "Lo único que necesitas hacer es:\n", 59 | "\n", 60 | "* Ir a la [página de descargas de Anaconda](http://continuum.io/downloads).\n", 61 | "* Seleccionar tu sistema operativo.\n", 62 | "* Descargar Anaconda." 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "\"Download\"" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "### 2. Instalación" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "Consulta las [instrucciones de instalación](http://docs.continuum.io/anaconda/install.html) de Anaconda para tu sistema operativo. En el caso de Windows y OS X, te encontrarás con los típicos instaladores gráficos a los que ya estás acostumbrado. Si te encuentras en Linux, deberás ejectuar el script de instalación desde la consola de comandos, así que recuerda comprobar que tienes bash instalado y asignar permisos de ejecución al script.\n", 84 | "\n", 85 | "En caso de que tengas cualquier caso de duda recuerda que __¡los buscadores de internet son tus mejores amigos!__\n", 86 | "\n", 87 | "¡Muy bien! ya tienes instalado Python en tu ordenador. Si te encuentras en Windows, desde `Inicio > Anaconda` verás una serie de herramientas de las que ahora dispones ¡no tengas miedo de abrirlas! En el caso de OS X, podrás acceder a un launcher con las mismas herramientas desde la carpeta `anaconda` dentro de tu carpeta personal. En Linux, debido al gran número de combinaciones de distribuciones más escritorios no tendrás dichos accesos directos gráficos (lo que no quiere decir que no puedas crearlos tú a posteriori ;p) pero, como comprobarás, no hacen ninguna falta y no forman parte de nuestra forma de trabajar en el curso.\n", 88 | "\n", 89 | "Ahora, vamos a actualizar Anaconda para asegurarnos de que tenemos nuestra distribución de Python con todos sus paquetes asl día para lo que abrimos una ventana de comandos (__Símbolo de sistema en Windows__ o __Terminal__ en OS X) y ejectuamos los siguientes comandos de actualización:\n", 90 | "\n", 91 | "```\n", 92 | "conda update anaconda\n", 93 | "conda update --all\n", 94 | "```\n", 95 | "\n", 96 | "Si experimentas cualquier clase de problema durante este proceso, [desinstala tu distribución de Anaconda](http://docs.continuum.io/anaconda/install.html) y vuelve a instalarla donde puedas asegurarte de tener una conexión a internet estable.\n", 97 | "\n", 98 | "Ya tenemos nuestra distribución de Python con todos los paquetes que necesitemos (y prácticamente todos los que en un futuro podamos necesitar). ¡Manos a la obra!\n", 99 | "\n", 100 | "\n" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "### 3. Descarga el material del curso" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "El material del curso está en GitHub. GitHub es una plataforma para alojar proyectos de software que además proporciona una serie de herramientas para el trabajo en equipo, digamos que es una especie de __red social-herramienta para escribir y compartir código. Tú no necesitarás saber nada sobre GitHub para seguir el curso.__" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "Simplemente ve a [nuestro repositorio](https://github.com/AeroPython/Curso-AeroPython-UC3M). En la parte derecha encontrarás un botón como éste: ![](../static/download_zip.png) \n", 122 | "\n", 123 | "__Púlsalo, guarda el archivo en tu ordenador y descomprímelo.__" 124 | ] 125 | }, 126 | { 127 | "cell_type": "markdown", 128 | "metadata": {}, 129 | "source": [ 130 | "### 4. Utiliza el material" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": {}, 136 | "source": [ 137 | "Para utilizar el material debes __abrir una línea de comandos en la carpeta que has descomprimido__.\n", 138 | "\n", 139 | "* En Windows, puedes hacer esto desde el explorador. Primero navega hasta la carpeta y luego usa `shift + clic-derecho` en un espacio vacío de la carpeta y pulsa sobre `Abrir ventana de comandos aquí`:\n", 140 | "\n", 141 | "![](../static/ventana_comandos_windows.png)\n", 142 | "\n", 143 | "* En OS X, puedes activar el menú [nuevo terminal en carpeta](http://appleadicto.com/mac/osx/ejecutar-el-terminal-de-os-x-desde-una-carpeta-del-finder/):\n", 144 | "![](../static/ventana_comandos_mac.png)\n", 145 | "\n", 146 | "* En Linux, la totalidad de escritorios disponibles tienen una opción para lanzar un terminal en una determinada carpeta (por ejemplo, el plugin `nautilus-open-terminal` en GNOME o pulsando `F4` dentro de Dolphin en KDE)." 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "Se abrirá una línea de comandos, teclea en ella:\n", 154 | "\n", 155 | "`ipython notebook` \n", 156 | "\n", 157 | "y pulsa Intro.\n", 158 | "\n", 159 | "__¡Es importante que la dirección que aparezca en la línea de comandos sea la correspondiente a la carpeta Curso_AeroPython, o determinados elementos como las imágenes incrustadas no se visualizarán correctamente!__\n", 160 | "\n", 161 | "Aparecerán unas cuantas líneas y __se abrirá tu navegador web predefinido. __No hace falta disponer de conexión a Internet__. Lo que está ocurriendo es que _\"tu navegador está mostrando lo que le manda el programa que se está ejecutando desde la línea de comandos\"_ (entiéndelo así ya tendrás tiempo de profundizar si quieres). Así que __no cierres la línea de comandos hasta que termines de usar el notebook y ya lo hayas guardado y cerrado en tu navegador.__" 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "metadata": {}, 167 | "source": [ 168 | "En esa ventana de tu navegador puedes moverte por las carpetas y ver los archivos con extensión `.ipynb`. __Ve a la carpeta `Notebooks` y abre la primera clase haciendo click sobre ella.__ Para cambiar el estilo (letra, colores...) ve a `File > Trust Notebook`.\n", 169 | "\n", 170 | "En esa primera clase se hace una pequeña introducción a Python. __Lee el principio con calma__ para saber cómo manejar el Notebook (también puedes usar la ayuda `Help > User Interface Tour` ) y __no tengas miedo de tocar y cambiar cosas a tu antojo__. No vas a romper tu ordenador y en una de malas, siempre puedes volverte a descargar todo de GitHub." 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": {}, 176 | "source": [ 177 | "##### ¡Ya estás listo para empezar!" 178 | ] 179 | }, 180 | { 181 | "cell_type": "markdown", 182 | "metadata": {}, 183 | "source": [ 184 | "---\n", 185 | "\n", 186 | "Clase en vídeo, parte del [Curso de Python para científicos e ingenieros](http://cacheme.org/curso-online-python-cientifico-ingenieros/) grabado en la Escuela Politécnica Superior de la Universidad de Alicante." 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": 1, 192 | "metadata": { 193 | "collapsed": false 194 | }, 195 | "outputs": [ 196 | { 197 | "data": { 198 | "text/html": [ 199 | "\n", 200 | " \n", 207 | " " 208 | ], 209 | "text/plain": [ 210 | "" 211 | ] 212 | }, 213 | "execution_count": 1, 214 | "metadata": {}, 215 | "output_type": "execute_result" 216 | } 217 | ], 218 | "source": [ 219 | "from IPython.display import YouTubeVideo\n", 220 | "\n", 221 | "YouTubeVideo(\"x4xegDME5C0\", width=560, height=315, list=\"PLGBbVX_WvN7as_DnOGcpkSsUyXB1G_wqb\")" 222 | ] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": {}, 227 | "source": [ 228 | "---" 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "metadata": {}, 234 | "source": [ 235 | "Si te ha gustado esta introducción y quieres contárselo a tus amigos:\n", 236 | "\n", 237 | "Tweet\n", 238 | "\n", 239 | "\n", 240 | "---" 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": {}, 246 | "source": [ 247 | "####

¡Síguenos en Twitter!" 248 | ] 249 | }, 250 | { 251 | "cell_type": "markdown", 252 | "metadata": {}, 253 | "source": [ 254 | "###### Follow @AeroPython " 255 | ] 256 | }, 257 | { 258 | "cell_type": "markdown", 259 | "metadata": {}, 260 | "source": [ 261 | "##### \"Licencia
Curso AeroPython por Juan Luis Cano Rodriguez y Alejandro Sáez Mollejo se distribuye bajo una Licencia Creative Commons Atribución 4.0 Internacional." 262 | ] 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": {}, 267 | "source": [ 268 | "##### " 269 | ] 270 | }, 271 | { 272 | "cell_type": "markdown", 273 | "metadata": {}, 274 | "source": [ 275 | "---\n", 276 | "_Las siguientes celdas contienen configuración del Notebook_\n", 277 | "\n", 278 | "_Para visualizar y utlizar los enlaces a Twitter el notebook debe ejecutarse como [seguro](http://ipython.org/ipython-doc/dev/notebook/security.html)_\n", 279 | "\n", 280 | " File > Trusted Notebook" 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": 2, 286 | "metadata": { 287 | "collapsed": false 288 | }, 289 | "outputs": [ 290 | { 291 | "data": { 292 | "text/html": [ 293 | "Follow @AeroPython\n", 294 | "" 295 | ], 296 | "text/plain": [ 297 | "" 298 | ] 299 | }, 300 | "metadata": {}, 301 | "output_type": "display_data" 302 | } 303 | ], 304 | "source": [ 305 | "%%html\n", 306 | "Follow @AeroPython\n", 307 | "" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": 1, 313 | "metadata": { 314 | "collapsed": false 315 | }, 316 | "outputs": [ 317 | { 318 | "data": { 319 | "text/html": [ 320 | "\n", 321 | "\n", 322 | "El estilo se ha aplicado =)\n", 323 | "\n", 324 | "\n", 461 | "\n" 477 | ], 478 | "text/plain": [ 479 | "" 480 | ] 481 | }, 482 | "execution_count": 1, 483 | "metadata": {}, 484 | "output_type": "execute_result" 485 | } 486 | ], 487 | "source": [ 488 | "# Esta celda da el estilo al notebook\n", 489 | "from IPython.core.display import HTML\n", 490 | "css_file = '../static/styles/style.css'\n", 491 | "HTML(open(css_file, \"r\").read())" 492 | ] 493 | } 494 | ], 495 | "metadata": { 496 | "kernelspec": { 497 | "display_name": "Python 3", 498 | "language": "python", 499 | "name": "python3" 500 | }, 501 | "language_info": { 502 | "codemirror_mode": { 503 | "name": "ipython", 504 | "version": 3 505 | }, 506 | "file_extension": ".py", 507 | "mimetype": "text/x-python", 508 | "name": "python", 509 | "nbconvert_exporter": "python", 510 | "pygments_lexer": "ipython3", 511 | "version": "3.4.3" 512 | } 513 | }, 514 | "nbformat": 4, 515 | "nbformat_minor": 0 516 | } 517 | -------------------------------------------------------------------------------- /notebooks_completos/Clase1b_Ejercicios.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\"AeroPython\"" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Clase 1b: Ejercicios prácticos" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "_En esta clase vamos a afianzar los conocimientos de Python que acabamos de adquirir haciendo algunos ejercicios, y así retener las peculiaridades de la sintaxis y aclarar algunos detalles a tener en cuenta cuando se trabaja en modo interactivo._" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "## Funciones" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "Lo más importante para programar, y no solo en Python, es saber organizar el código en piezas más pequeñas que hagan tareas independientes y combinarlas entre sí. Las **funciones** son el primer nivel de organización del código: reciben unas *entradas*, las *procesan* y devuelven unas *salidas*." 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "![Black box](../static/blackbox.jpg)" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "### Ejercicio 1: Función de una entrada" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "Vamos a crear una función que compruebe si un número es mayor o menor que cinco. La salida ahora no nos importa mucho: lo importante es que al declarar los argumentos de entrada en la definición de la función, podremos usarlos dentro de ella con el nombre que decidamos." 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "
¡No olvides los dos puntos! Si el sangrado del código no avanza automáticamente, es que te los has dejado.
" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 1, 69 | "metadata": { 70 | "collapsed": false 71 | }, 72 | "outputs": [], 73 | "source": [ 74 | "def comparar_cinco(num):\n", 75 | " if num < 5:\n", 76 | " return \"El número es menor que cinco\"\n", 77 | " elif num == 5:\n", 78 | " return \"El número es igual a cinco\"\n", 79 | " else:\n", 80 | " return \"El número es mayor que cinco\"" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 2, 86 | "metadata": { 87 | "collapsed": false 88 | }, 89 | "outputs": [ 90 | { 91 | "name": "stdout", 92 | "output_type": "stream", 93 | "text": [ 94 | "El número es menor que cinco\n" 95 | ] 96 | } 97 | ], 98 | "source": [ 99 | "print(comparar_cinco(2))" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 3, 105 | "metadata": { 106 | "collapsed": false 107 | }, 108 | "outputs": [ 109 | { 110 | "name": "stdout", 111 | "output_type": "stream", 112 | "text": [ 113 | "El número es mayor que cinco\n" 114 | ] 115 | } 116 | ], 117 | "source": [ 118 | "mi_numero = 7 # Aquí la variable se llama `mi_numero`\n", 119 | "print(comparar_cinco(mi_numero)) # ¡Dentro de la función eso me da igual!" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "
Apuntes:\n", 127 | "\n", 128 | "
  • Podríamos haber puesto un `elif num > 5` en la última parte en vez de un `else`. En este caso es obvio, pero en otros puede no ser tan evidente.
  • \n", 129 | "
  • Algunos prefieren sacar los `return` fuera del condicional, o incluso que solo haya uno. http://stackoverflow.com/q/9191388/554319 ¡Cuestión de gustos!
  • \n", 130 | "
\n", 131 | "\n", 132 | "
" 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "metadata": {}, 138 | "source": [ 139 | "### Ejercicio 2: Sumatorio" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "Vamos a escribir ahora una función que sume los `n` primeros números naturales. Observa que podemos escribir una **cadena de documentación** (_docstring_) justo debajo de la definición de la función para explicar lo que hace." 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 4, 152 | "metadata": { 153 | "collapsed": false 154 | }, 155 | "outputs": [], 156 | "source": [ 157 | "def sumatorio(num):\n", 158 | " \"\"\"Suma los `num` primeros números.\n", 159 | "\n", 160 | " Ejemplos\n", 161 | " --------\n", 162 | " >>> sumatorio(4)\n", 163 | " 10\n", 164 | "\n", 165 | " \"\"\"\n", 166 | " suma = 0\n", 167 | " for nn in range(1, num + 1):\n", 168 | " suma = nn + suma\n", 169 | " return suma" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": {}, 175 | "source": [ 176 | "Lo que hemos hecho ha sido inicializar el valor de la suma a 0 e ir acumulando en ella los `num` primeros números naturales." 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 5, 182 | "metadata": { 183 | "collapsed": false 184 | }, 185 | "outputs": [ 186 | { 187 | "data": { 188 | "text/plain": [ 189 | "10" 190 | ] 191 | }, 192 | "execution_count": 5, 193 | "metadata": {}, 194 | "output_type": "execute_result" 195 | } 196 | ], 197 | "source": [ 198 | "sumatorio(4)" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 6, 204 | "metadata": { 205 | "collapsed": false 206 | }, 207 | "outputs": [ 208 | { 209 | "name": "stdout", 210 | "output_type": "stream", 211 | "text": [ 212 | "Help on function sumatorio in module __main__:\n", 213 | "\n", 214 | "sumatorio(num)\n", 215 | " Suma los `num` primeros números.\n", 216 | " \n", 217 | " Ejemplos\n", 218 | " --------\n", 219 | " >>> sumatorio(4)\n", 220 | " 10\n", 221 | "\n" 222 | ] 223 | } 224 | ], 225 | "source": [ 226 | "help(sumatorio)" 227 | ] 228 | }, 229 | { 230 | "cell_type": "markdown", 231 | "metadata": {}, 232 | "source": [ 233 | "
Observa lo que sucede si no inicializamos la suma:
" 234 | ] 235 | }, 236 | { 237 | "cell_type": "code", 238 | "execution_count": 7, 239 | "metadata": { 240 | "collapsed": false 241 | }, 242 | "outputs": [], 243 | "source": [ 244 | "def sumatorio_mal(num):\n", 245 | " for nn in range(1, num + 1):\n", 246 | " suma = nn + suma\n", 247 | " return suma" 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": 8, 253 | "metadata": { 254 | "collapsed": false 255 | }, 256 | "outputs": [ 257 | { 258 | "ename": "UnboundLocalError", 259 | "evalue": "local variable 'suma' referenced before assignment", 260 | "output_type": "error", 261 | "traceback": [ 262 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 263 | "\u001b[1;31mUnboundLocalError\u001b[0m Traceback (most recent call last)", 264 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0msumatorio_mal\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 265 | "\u001b[1;32m\u001b[0m in \u001b[0;36msumatorio_mal\u001b[1;34m(num)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0msumatorio_mal\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnum\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mnn\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnum\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0msuma\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnn\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0msuma\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0msuma\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 266 | "\u001b[1;31mUnboundLocalError\u001b[0m: local variable 'suma' referenced before assignment" 267 | ] 268 | } 269 | ], 270 | "source": [ 271 | "sumatorio_mal(4)" 272 | ] 273 | }, 274 | { 275 | "cell_type": "markdown", 276 | "metadata": {}, 277 | "source": [ 278 | "Para comprobar el resultado correcto, nada como acudir a la función `sum` de Python, que suma los elementos que le pasemos:" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": 9, 284 | "metadata": { 285 | "collapsed": false 286 | }, 287 | "outputs": [ 288 | { 289 | "data": { 290 | "text/plain": [ 291 | "[1, 2, 3, 4]" 292 | ] 293 | }, 294 | "execution_count": 9, 295 | "metadata": {}, 296 | "output_type": "execute_result" 297 | } 298 | ], 299 | "source": [ 300 | "list(range(1, 4 + 1))" 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": 10, 306 | "metadata": { 307 | "collapsed": false 308 | }, 309 | "outputs": [ 310 | { 311 | "data": { 312 | "text/plain": [ 313 | "10" 314 | ] 315 | }, 316 | "execution_count": 10, 317 | "metadata": {}, 318 | "output_type": "execute_result" 319 | } 320 | ], 321 | "source": [ 322 | "sum(range(1, 4 + 1))" 323 | ] 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "metadata": {}, 328 | "source": [ 329 | "### Ejercicio 3: Sumatorio con cota superior" 330 | ] 331 | }, 332 | { 333 | "cell_type": "markdown", 334 | "metadata": {}, 335 | "source": [ 336 | "Ahora nuestra función es un poco más rara: tiene que sumar los $n$ primeros números naturales y no pasarse de un determinado límite. Además, queremos el valor de la suma." 337 | ] 338 | }, 339 | { 340 | "cell_type": "code", 341 | "execution_count": 11, 342 | "metadata": { 343 | "collapsed": false 344 | }, 345 | "outputs": [], 346 | "source": [ 347 | "def suma_tope(tope):\n", 348 | " \"\"\"Suma números naturales consecutivos hasta un tope.\n", 349 | "\n", 350 | " \"\"\"\n", 351 | " suma = 0\n", 352 | " nn = 1\n", 353 | " while suma + nn <= tope:\n", 354 | " suma = suma + nn\n", 355 | " nn += 1\n", 356 | " return suma" 357 | ] 358 | }, 359 | { 360 | "cell_type": "code", 361 | "execution_count": 12, 362 | "metadata": { 363 | "collapsed": false 364 | }, 365 | "outputs": [ 366 | { 367 | "data": { 368 | "text/plain": [ 369 | "6" 370 | ] 371 | }, 372 | "execution_count": 12, 373 | "metadata": {}, 374 | "output_type": "execute_result" 375 | } 376 | ], 377 | "source": [ 378 | "suma_tope(9)" 379 | ] 380 | }, 381 | { 382 | "cell_type": "code", 383 | "execution_count": 13, 384 | "metadata": { 385 | "collapsed": false 386 | }, 387 | "outputs": [ 388 | { 389 | "data": { 390 | "text/plain": [ 391 | "True" 392 | ] 393 | }, 394 | "execution_count": 13, 395 | "metadata": {}, 396 | "output_type": "execute_result" 397 | } 398 | ], 399 | "source": [ 400 | "suma_tope(9) == 1 + 2 + 3" 401 | ] 402 | }, 403 | { 404 | "cell_type": "code", 405 | "execution_count": 14, 406 | "metadata": { 407 | "collapsed": false 408 | }, 409 | "outputs": [ 410 | { 411 | "data": { 412 | "text/plain": [ 413 | "True" 414 | ] 415 | }, 416 | "execution_count": 14, 417 | "metadata": {}, 418 | "output_type": "execute_result" 419 | } 420 | ], 421 | "source": [ 422 | "suma_tope(10) == 1 + 2 + 3 + 4" 423 | ] 424 | }, 425 | { 426 | "cell_type": "markdown", 427 | "metadata": {}, 428 | "source": [ 429 | "La palabra clave `assert` recibe una expresión verdadera o falsa, y falla si es falsa. Si es verdadera no hace nada, con lo cual es perfecto para hacer comprobaciones a mitad del código que no estorben mucho." 430 | ] 431 | }, 432 | { 433 | "cell_type": "code", 434 | "execution_count": 15, 435 | "metadata": { 436 | "collapsed": false 437 | }, 438 | "outputs": [], 439 | "source": [ 440 | "assert suma_tope(11) == 1 + 2 + 3 + 4" 441 | ] 442 | }, 443 | { 444 | "cell_type": "code", 445 | "execution_count": 16, 446 | "metadata": { 447 | "collapsed": false 448 | }, 449 | "outputs": [ 450 | { 451 | "ename": "AssertionError", 452 | "evalue": "", 453 | "output_type": "error", 454 | "traceback": [ 455 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 456 | "\u001b[1;31mAssertionError\u001b[0m Traceback (most recent call last)", 457 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32massert\u001b[0m \u001b[0msuma_tope\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m10\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;36m1\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m2\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m3\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m4\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 458 | "\u001b[1;31mAssertionError\u001b[0m: " 459 | ] 460 | } 461 | ], 462 | "source": [ 463 | "assert suma_tope(10 + 5) == 1 + 2 + 3 + 4" 464 | ] 465 | }, 466 | { 467 | "cell_type": "markdown", 468 | "metadata": {}, 469 | "source": [ 470 | "### Ejercicio 4: Normativa de exámenes" 471 | ] 472 | }, 473 | { 474 | "cell_type": "markdown", 475 | "metadata": {}, 476 | "source": [ 477 | "La normativa de exámenes de la UPM es: *\"si un examen dura más de 3 horas, entonces debe tener un descanso\"*. Los argumentos de la función son el tiempo en horas y un valor `True` o `False` que indica si hay descanso o no, y la función devuelve si el examen cumple o no con la normativa." 478 | ] 479 | }, 480 | { 481 | "cell_type": "code", 482 | "execution_count": 17, 483 | "metadata": { 484 | "collapsed": false 485 | }, 486 | "outputs": [], 487 | "source": [ 488 | "def cumple_normativa(tiempo, descanso):\n", 489 | " \"\"\"Comprueba si un examen cumple la normativa de la UPM.\n", 490 | "\n", 491 | " \"\"\"\n", 492 | " if tiempo <= 3:\n", 493 | " return True\n", 494 | " else:\n", 495 | " #if descanso:\n", 496 | " # return True\n", 497 | " #else:\n", 498 | " # return False\n", 499 | " return descanso # ¡Equivalente!" 500 | ] 501 | }, 502 | { 503 | "cell_type": "code", 504 | "execution_count": 18, 505 | "metadata": { 506 | "collapsed": false 507 | }, 508 | "outputs": [ 509 | { 510 | "data": { 511 | "text/plain": [ 512 | "True" 513 | ] 514 | }, 515 | "execution_count": 18, 516 | "metadata": {}, 517 | "output_type": "execute_result" 518 | } 519 | ], 520 | "source": [ 521 | "cumple_normativa(2, False)" 522 | ] 523 | }, 524 | { 525 | "cell_type": "code", 526 | "execution_count": 19, 527 | "metadata": { 528 | "collapsed": false 529 | }, 530 | "outputs": [ 531 | { 532 | "name": "stdout", 533 | "output_type": "stream", 534 | "text": [ 535 | "¡Habla con Delegación de Alumnos!\n" 536 | ] 537 | } 538 | ], 539 | "source": [ 540 | "if not cumple_normativa(5, descanso=False):\n", 541 | " print(\"¡Habla con Delegación de Alumnos!\")" 542 | ] 543 | }, 544 | { 545 | "cell_type": "markdown", 546 | "metadata": {}, 547 | "source": [ 548 | "### Ejercicio 5" 549 | ] 550 | }, 551 | { 552 | "cell_type": "markdown", 553 | "metadata": {}, 554 | "source": [ 555 | "Hallar $x = \\sqrt{S}$.\n", 556 | "\n", 557 | "1. $\\displaystyle \\tilde{x} \\leftarrow \\frac{S}{2}$.\n", 558 | "2. $\\displaystyle \\tilde{x} \\leftarrow \\frac{1}{2}\\left(\\tilde{x} + \\frac{S}{\\tilde{x}}\\right)$.\n", 559 | "3. Repetir (2) hasta que se alcance un límite de iteraciones o un criterio de convergencia.\n", 560 | "\n", 561 | "http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method" 562 | ] 563 | }, 564 | { 565 | "cell_type": "code", 566 | "execution_count": 20, 567 | "metadata": { 568 | "collapsed": false 569 | }, 570 | "outputs": [], 571 | "source": [ 572 | "def raiz(S):\n", 573 | " x = S / 2\n", 574 | " while True:\n", 575 | " temp = x\n", 576 | " x = (x + S / x) / 2\n", 577 | " if temp == x:\n", 578 | " return x" 579 | ] 580 | }, 581 | { 582 | "cell_type": "markdown", 583 | "metadata": {}, 584 | "source": [ 585 | "Aquí estoy usando un truco de la aritmética en punto flotante: como la convergencia se alcanza rápidamente, llega un momento en que el error es menor que la precisión de la máquina y el valor no cambia de un paso a otro." 586 | ] 587 | }, 588 | { 589 | "cell_type": "code", 590 | "execution_count": 21, 591 | "metadata": { 592 | "collapsed": false 593 | }, 594 | "outputs": [ 595 | { 596 | "data": { 597 | "text/plain": [ 598 | "3.162277660168379" 599 | ] 600 | }, 601 | "execution_count": 21, 602 | "metadata": {}, 603 | "output_type": "execute_result" 604 | } 605 | ], 606 | "source": [ 607 | "raiz(10)" 608 | ] 609 | }, 610 | { 611 | "cell_type": "markdown", 612 | "metadata": {}, 613 | "source": [ 614 | "
Se deja como ejercicio implementar otras condiciones de convergencia: error relativo por debajo de un umbral o número máximo de iteraciones.
" 615 | ] 616 | }, 617 | { 618 | "cell_type": "code", 619 | "execution_count": 22, 620 | "metadata": { 621 | "collapsed": false 622 | }, 623 | "outputs": [ 624 | { 625 | "data": { 626 | "text/plain": [ 627 | "3.1622776601683795" 628 | ] 629 | }, 630 | "execution_count": 22, 631 | "metadata": {}, 632 | "output_type": "execute_result" 633 | } 634 | ], 635 | "source": [ 636 | "import math\n", 637 | "math.sqrt(10)" 638 | ] 639 | }, 640 | { 641 | "cell_type": "code", 642 | "execution_count": 23, 643 | "metadata": { 644 | "collapsed": false 645 | }, 646 | "outputs": [ 647 | { 648 | "data": { 649 | "text/plain": [ 650 | "9.999999999999998" 651 | ] 652 | }, 653 | "execution_count": 23, 654 | "metadata": {}, 655 | "output_type": "execute_result" 656 | } 657 | ], 658 | "source": [ 659 | "raiz(10) ** 2" 660 | ] 661 | }, 662 | { 663 | "cell_type": "code", 664 | "execution_count": 24, 665 | "metadata": { 666 | "collapsed": false 667 | }, 668 | "outputs": [ 669 | { 670 | "data": { 671 | "text/plain": [ 672 | "10.000000000000002" 673 | ] 674 | }, 675 | "execution_count": 24, 676 | "metadata": {}, 677 | "output_type": "execute_result" 678 | } 679 | ], 680 | "source": [ 681 | "math.sqrt(10) ** 2" 682 | ] 683 | }, 684 | { 685 | "cell_type": "markdown", 686 | "metadata": {}, 687 | "source": [ 688 | "Ahora tienes curiosidad, ¿verdad? :) http://puntoflotante.org/" 689 | ] 690 | }, 691 | { 692 | "cell_type": "markdown", 693 | "metadata": {}, 694 | "source": [ 695 | "### Ejercicio 6" 696 | ] 697 | }, 698 | { 699 | "cell_type": "markdown", 700 | "metadata": {}, 701 | "source": [ 702 | "Secuencia de Fibonacci: $F_n = F_{n - 1} + F_{n - 2}$, con $F_0 = 0$ y $F_1 = 1$.\n", 703 | "\n", 704 | "$$0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...$$" 705 | ] 706 | }, 707 | { 708 | "cell_type": "markdown", 709 | "metadata": {}, 710 | "source": [ 711 | "Con iteración:" 712 | ] 713 | }, 714 | { 715 | "cell_type": "code", 716 | "execution_count": 25, 717 | "metadata": { 718 | "collapsed": false 719 | }, 720 | "outputs": [], 721 | "source": [ 722 | "def fib(n):\n", 723 | " a, b = 0, 1\n", 724 | " for i in range(n):\n", 725 | " a, b = b, a + b # Bendita asignación múltiple\n", 726 | " return a" 727 | ] 728 | }, 729 | { 730 | "cell_type": "code", 731 | "execution_count": 26, 732 | "metadata": { 733 | "collapsed": false 734 | }, 735 | "outputs": [ 736 | { 737 | "data": { 738 | "text/plain": [ 739 | "(0, 2, 55)" 740 | ] 741 | }, 742 | "execution_count": 26, 743 | "metadata": {}, 744 | "output_type": "execute_result" 745 | } 746 | ], 747 | "source": [ 748 | "fib(0), fib(3), fib(10)" 749 | ] 750 | }, 751 | { 752 | "cell_type": "markdown", 753 | "metadata": {}, 754 | "source": [ 755 | "Con recursión:" 756 | ] 757 | }, 758 | { 759 | "cell_type": "code", 760 | "execution_count": 27, 761 | "metadata": { 762 | "collapsed": false 763 | }, 764 | "outputs": [], 765 | "source": [ 766 | "def fib_recursivo(n):\n", 767 | " if n == 0:\n", 768 | " res = 0\n", 769 | " elif n == 1:\n", 770 | " res = 1\n", 771 | " else:\n", 772 | " res = fib_recursivo(n - 1) + fib_recursivo(n - 2)\n", 773 | " return res" 774 | ] 775 | }, 776 | { 777 | "cell_type": "markdown", 778 | "metadata": {}, 779 | "source": [ 780 | "Imprimir una lista con los $n$ primeros:" 781 | ] 782 | }, 783 | { 784 | "cell_type": "code", 785 | "execution_count": 28, 786 | "metadata": { 787 | "collapsed": false 788 | }, 789 | "outputs": [], 790 | "source": [ 791 | "def n_primeros(n):\n", 792 | " F = fib_recursivo\n", 793 | " lista = []\n", 794 | " for ii in range(n):\n", 795 | " lista.append(F(ii))\n", 796 | " return lista" 797 | ] 798 | }, 799 | { 800 | "cell_type": "code", 801 | "execution_count": 29, 802 | "metadata": { 803 | "collapsed": false 804 | }, 805 | "outputs": [ 806 | { 807 | "data": { 808 | "text/plain": [ 809 | "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]" 810 | ] 811 | }, 812 | "execution_count": 29, 813 | "metadata": {}, 814 | "output_type": "execute_result" 815 | } 816 | ], 817 | "source": [ 818 | "n_primeros(10)" 819 | ] 820 | }, 821 | { 822 | "cell_type": "markdown", 823 | "metadata": {}, 824 | "source": [ 825 | "---" 826 | ] 827 | }, 828 | { 829 | "cell_type": "markdown", 830 | "metadata": {}, 831 | "source": [ 832 | "_En esta clase hemos visto cómo crear funciones que encapsulen tareas de nuestro programa y las hemos aplicado para respondernos ciertas preguntas sencillas._\n", 833 | "\n", 834 | "**Referencias**\n", 835 | "\n", 836 | "* Libro \"Learn Python the Hard Way\" http://learnpythonthehardway.org/book/\n", 837 | "* Python Tutor, para visualizar código Python paso a paso http://pythontutor.com/\n", 838 | "* Libro \"How To Think Like a Computer Scientist\" http://interactivepython.org/runestone/static/thinkcspy/toc.html\n", 839 | "* Project Euler: ejercicios para aprender Python https://projecteuler.net/problems\n", 840 | "* Python Challenge (!) http://www.pythonchallenge.com/" 841 | ] 842 | }, 843 | { 844 | "cell_type": "markdown", 845 | "metadata": {}, 846 | "source": [ 847 | "Si te ha gustado esta clase:\n", 848 | "\n", 849 | "Tweet\n", 850 | "\n", 851 | "\n", 852 | "---" 853 | ] 854 | }, 855 | { 856 | "cell_type": "markdown", 857 | "metadata": {}, 858 | "source": [ 859 | "####

¡Síguenos en Twitter!" 860 | ] 861 | }, 862 | { 863 | "cell_type": "markdown", 864 | "metadata": {}, 865 | "source": [ 866 | "###### Follow @AeroPython " 867 | ] 868 | }, 869 | { 870 | "cell_type": "markdown", 871 | "metadata": {}, 872 | "source": [ 873 | "##### \"Licencia
Curso AeroPython por Juan Luis Cano Rodriguez y Alejandro Sáez Mollejo se distribuye bajo una Licencia Creative Commons Atribución 4.0 Internacional." 874 | ] 875 | }, 876 | { 877 | "cell_type": "markdown", 878 | "metadata": {}, 879 | "source": [ 880 | "##### " 881 | ] 882 | }, 883 | { 884 | "cell_type": "markdown", 885 | "metadata": {}, 886 | "source": [ 887 | "---\n", 888 | "_Las siguientes celdas contienen configuración del Notebook_\n", 889 | "\n", 890 | "_Para visualizar y utlizar los enlaces a Twitter el notebook debe ejecutarse como [seguro](http://ipython.org/ipython-doc/dev/notebook/security.html)_\n", 891 | "\n", 892 | " File > Trusted Notebook" 893 | ] 894 | }, 895 | { 896 | "cell_type": "code", 897 | "execution_count": 2, 898 | "metadata": { 899 | "collapsed": false 900 | }, 901 | "outputs": [ 902 | { 903 | "data": { 904 | "text/html": [ 905 | "Follow @AeroPython\n", 906 | "" 907 | ], 908 | "text/plain": [ 909 | "" 910 | ] 911 | }, 912 | "metadata": {}, 913 | "output_type": "display_data" 914 | } 915 | ], 916 | "source": [ 917 | "%%html\n", 918 | "Follow @AeroPython\n", 919 | "" 920 | ] 921 | }, 922 | { 923 | "cell_type": "code", 924 | "execution_count": 1, 925 | "metadata": { 926 | "collapsed": false 927 | }, 928 | "outputs": [ 929 | { 930 | "data": { 931 | "text/html": [ 932 | "\n", 933 | "\n", 934 | "El estilo se ha aplicado =)\n", 935 | "\n", 936 | "\n", 1073 | "\n" 1089 | ], 1090 | "text/plain": [ 1091 | "" 1092 | ] 1093 | }, 1094 | "execution_count": 1, 1095 | "metadata": {}, 1096 | "output_type": "execute_result" 1097 | } 1098 | ], 1099 | "source": [ 1100 | "# Esta celda da el estilo al notebook\n", 1101 | "from IPython.core.display import HTML\n", 1102 | "css_file = '../static/styles/style.css'\n", 1103 | "HTML(open(css_file, \"r\").read())" 1104 | ] 1105 | } 1106 | ], 1107 | "metadata": { 1108 | "kernelspec": { 1109 | "display_name": "Python 3", 1110 | "language": "python", 1111 | "name": "python3" 1112 | }, 1113 | "language_info": { 1114 | "codemirror_mode": { 1115 | "name": "ipython", 1116 | "version": 3 1117 | }, 1118 | "file_extension": ".py", 1119 | "mimetype": "text/x-python", 1120 | "name": "python", 1121 | "nbconvert_exporter": "python", 1122 | "pygments_lexer": "ipython3", 1123 | "version": "3.4.3" 1124 | } 1125 | }, 1126 | "nbformat": 4, 1127 | "nbformat_minor": 0 1128 | } 1129 | -------------------------------------------------------------------------------- /notebooks_vacios/Clase2a_NumPy_intro.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\"AeroPython\"" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Clase 2a: Introducción a NumPy" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "_Hasta ahora hemos visto los tipos de datos más básicos que nos ofrece Python: integer, real, complex, boolean, list, tuple... Pero ¿no echas algo de menos? Efectivamente, los __arrays__. _\n", 22 | "\n", 23 | "_Durante esta nos adentraremos en el paquete NumPy: veremos como los arrays mejoran la eficiencia de nuestro código, aprenderemos a crearlos y a operar con ellos_." 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "## ¿Qué es un array? " 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "Un array es un __bloque de memoria que contiene elementos del mismo tipo__. Básicamente:\n", 38 | "\n", 39 | "* nos _recuerdan_ a los vectores, matrices, tensores...\n", 40 | "* podemos almacenar el array con un nombre y acceder a sus __elementos__ mediante sus __índices__.\n", 41 | "* ayudan a gestionar de manera eficiente la memoria y a acelerar los cálculos.\n", 42 | "\n", 43 | "\n", 44 | "---\n", 45 | "\n", 46 | "| Índice | 0 | 1 | 2 | 3 | ... | n-1 | n |\n", 47 | "| ---------- | :---: | :---: | :---: | :---: | :---: | :---: | :---: |\n", 48 | "| Valor | 2.1 | 3.6 | 7.8 | 1.5 | ... | 5.4 | 6.3 |\n", 49 | "\n", 50 | "---\n", 51 | "\n", 52 | "__¿Qué solemos guardar en arrays?__\n", 53 | "\n", 54 | "* Vectores y matrices.\n", 55 | "* Datos de experimentos:\n", 56 | " - En distintos instantes discretos.\n", 57 | " - En distintos puntos del espacio.\n", 58 | "* Resultado de evaluar funciones con los datos anteriores.\n", 59 | "* Discretizaciones para usar algoritmos de: integración, derivación, interpolación...\n", 60 | "* ... " 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "## ¿Qué es NumPy?" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "NumPy es un paquete fundamental para la programación científica que __proporciona un objeto tipo array__ para almacenar datos de forma eficiente y una serie de __funciones__ para operar y manipular esos datos.\n", 75 | "Para usar NumPy lo primero que debemos hacer es importarlo:" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": { 82 | "collapsed": false 83 | }, 84 | "outputs": [], 85 | "source": [ 86 | "\n", 87 | "#para ver la versión que tenemos instalada:\n" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "## Nuestro primer array" 95 | ] 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "metadata": {}, 100 | "source": [ 101 | "¿No decíamos que Python era fácil? Pues __creemos nuestros primeros arrays__:" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": { 108 | "collapsed": false 109 | }, 110 | "outputs": [], 111 | "source": [ 112 | "# Array de una dimensión\n" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": { 119 | "collapsed": false 120 | }, 121 | "outputs": [], 122 | "source": [ 123 | "# Podemos usar print\n" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": null, 129 | "metadata": { 130 | "collapsed": false 131 | }, 132 | "outputs": [], 133 | "source": [ 134 | "# Comprobar el tipo de mi_primer_array\n" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": null, 140 | "metadata": { 141 | "collapsed": false 142 | }, 143 | "outputs": [], 144 | "source": [ 145 | "# Comprobar el tipo de datos que contiene\n" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "metadata": {}, 151 | "source": [ 152 | "Los arrays de una dimensión se crean pasándole una lista como argumento a la función `np.array`. Para crear un array de dos dimensiones le pasaremos una _lista de listas_:" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "metadata": { 159 | "collapsed": false 160 | }, 161 | "outputs": [], 162 | "source": [ 163 | "# Array de dos dimensiones\n" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": {}, 169 | "source": [ 170 | "
Podemos continuar en la siguiente línea usando `\\`, pero no es necesario escribirlo dentro de paréntesis o corchetes
" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": {}, 176 | "source": [ 177 | "Esto sería una buena manera de definirlo, de acuerdo con el [PEP 8 (indentation)](http://legacy.python.org/dev/peps/pep-0008/#indentation):" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": null, 183 | "metadata": { 184 | "collapsed": false 185 | }, 186 | "outputs": [], 187 | "source": [] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": {}, 192 | "source": [ 193 | "### Funciones y constantes de NumPy" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "Hemos dicho que NumPy también incorporá __funciones__. Un ejemplo sencillo:" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": null, 206 | "metadata": { 207 | "collapsed": false 208 | }, 209 | "outputs": [], 210 | "source": [ 211 | "# Suma\n" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": null, 217 | "metadata": { 218 | "collapsed": false 219 | }, 220 | "outputs": [], 221 | "source": [ 222 | "# Máximo\n" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": null, 228 | "metadata": { 229 | "collapsed": false 230 | }, 231 | "outputs": [], 232 | "source": [ 233 | "# Seno\n" 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "metadata": {}, 239 | "source": [ 240 | "Y algunas __constantes__ que podemos neccesitar:" 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": null, 246 | "metadata": { 247 | "collapsed": false 248 | }, 249 | "outputs": [], 250 | "source": [] 251 | }, 252 | { 253 | "cell_type": "markdown", 254 | "metadata": {}, 255 | "source": [ 256 | "## Características de los arrays de NumPy" 257 | ] 258 | }, 259 | { 260 | "cell_type": "markdown", 261 | "metadata": {}, 262 | "source": [ 263 | "El objeto tipo array que proporciona NumPy (Python ya dispone de un tipo array que sirve para almacenar elementos de igual tipo pero no proporciona toda la artillería matemática necesaria como para hacer operaciones de manera rápida y eficiente) se caracteriza por:" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "### 1) Homogeneidad de tipo:" 271 | ] 272 | }, 273 | { 274 | "cell_type": "markdown", 275 | "metadata": {}, 276 | "source": [ 277 | "Comencemos viendo que ocurre con las __listas__:" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": null, 283 | "metadata": { 284 | "collapsed": false 285 | }, 286 | "outputs": [], 287 | "source": [] 288 | }, 289 | { 290 | "cell_type": "markdown", 291 | "metadata": {}, 292 | "source": [ 293 | "En el caso de los __arrays__:" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "execution_count": null, 299 | "metadata": { 300 | "collapsed": false 301 | }, 302 | "outputs": [], 303 | "source": [] 304 | }, 305 | { 306 | "cell_type": "markdown", 307 | "metadata": {}, 308 | "source": [ 309 | "__¿Todo bien? Pues no__. Mientras que en la lista cada elemento conserva su tipo, en el array, todos han de tener el mismo y NumPy ha considerado que todos van a ser string." 310 | ] 311 | }, 312 | { 313 | "cell_type": "markdown", 314 | "metadata": {}, 315 | "source": [ 316 | "### 2) Tamaño fijo en el momento de la creación:" 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": {}, 322 | "source": [ 323 | "__¡Tranquilo!__ los __allocate__ son automáticos...\n", 324 | "\n", 325 | "Igual que en el caso anterior, comencemos con la __lista__:" 326 | ] 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": null, 331 | "metadata": { 332 | "collapsed": false 333 | }, 334 | "outputs": [], 335 | "source": [] 336 | }, 337 | { 338 | "cell_type": "code", 339 | "execution_count": null, 340 | "metadata": { 341 | "collapsed": false 342 | }, 343 | "outputs": [], 344 | "source": [] 345 | }, 346 | { 347 | "cell_type": "markdown", 348 | "metadata": {}, 349 | "source": [ 350 | "Si consultamos la ayuda de la función `np.append` escribiendo en una celda `help(np.append)` podemos leer:\n", 351 | "\n", 352 | " Returns\n", 353 | " -------\n", 354 | " append : ndarray\n", 355 | " A copy of `arr` with `values` appended to `axis`. Note that `append` does not occur in-place: a new array is allocated and filled. If `axis` is None, `out` is a flattened array." 356 | ] 357 | }, 358 | { 359 | "cell_type": "markdown", 360 | "metadata": {}, 361 | "source": [ 362 | "### 3) Eficiencia" 363 | ] 364 | }, 365 | { 366 | "cell_type": "markdown", 367 | "metadata": {}, 368 | "source": [ 369 | "Hasta el momento los arrays han demostrado ser bastante menos flexibles que las listas, luego olvidemos estos últimos 10 minutos y manejemos siempre listas... ¿no? ¡Pues no! Los arrays realizan una gestión de la memoria mucho más eficiente que mejora el rendimiento.\n", 370 | "\n", 371 | "Prestemos atención ahora a la velocidad de ejecución gracias a la _función mágica_ `%%timeit`, que colocada al inicio de una celda nos indicará el tiempo que tarda en ejecutarse. " 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": null, 377 | "metadata": { 378 | "collapsed": false 379 | }, 380 | "outputs": [], 381 | "source": [] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "execution_count": null, 386 | "metadata": { 387 | "collapsed": false 388 | }, 389 | "outputs": [], 390 | "source": [] 391 | }, 392 | { 393 | "cell_type": "code", 394 | "execution_count": null, 395 | "metadata": { 396 | "collapsed": false 397 | }, 398 | "outputs": [], 399 | "source": [] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": null, 404 | "metadata": { 405 | "collapsed": false 406 | }, 407 | "outputs": [], 408 | "source": [] 409 | }, 410 | { 411 | "cell_type": "markdown", 412 | "metadata": {}, 413 | "source": [ 414 | "Como ves, las mejoras en este caso son de 2 órdenes de magnitud. __NumPy nos ofrece funciones que se ejecutan prácticamente en tiempos de lenguaje compilado (Fortran, C, C++) y optimizado, pero escribiendo mucho menos código y con un nivel de abstracción mayor__. Conociendo una serie de buenas prácticas, podremos competir en velocidad con nuestros códigos en Python. Para casos en los que no sea posible, existen herramientas que nos permiten ejecutar desde Python nuestros códigos en otros lengujes como [f2py](http://docs.scipy.org/doc/numpy-dev/f2py/). Este tema puede resultarte algo avanzado a estas alturas, pero bastante útil; puedes consultar este [artículo de pybonacci](http://pybonacci.org/2013/02/22/integrar-fortran-con-python-usando-f2py/9) si lo necesitas." 415 | ] 416 | }, 417 | { 418 | "cell_type": "markdown", 419 | "metadata": {}, 420 | "source": [ 421 | "## Funciones para crear arrays" 422 | ] 423 | }, 424 | { 425 | "cell_type": "markdown", 426 | "metadata": {}, 427 | "source": [ 428 | "¿Demasiada teoría? vayamos a la práctica. Ya hemos visto que la función `np.array()` nos permite crear arrays con los valores que nosotros introduzcamos manualmente a través de listas. Más adelante, aprenderemos a leer ficheros y almacenarlos en arrays. Mientras tanto, ¿qué puede hacernos falta?" 429 | ] 430 | }, 431 | { 432 | "cell_type": "markdown", 433 | "metadata": {}, 434 | "source": [ 435 | "#### array de ceros" 436 | ] 437 | }, 438 | { 439 | "cell_type": "code", 440 | "execution_count": null, 441 | "metadata": { 442 | "collapsed": false 443 | }, 444 | "outputs": [], 445 | "source": [ 446 | "# En una dimensión\n" 447 | ] 448 | }, 449 | { 450 | "cell_type": "code", 451 | "execution_count": null, 452 | "metadata": { 453 | "collapsed": false 454 | }, 455 | "outputs": [], 456 | "source": [ 457 | "# En dos dimensiones\n" 458 | ] 459 | }, 460 | { 461 | "cell_type": "markdown", 462 | "metadata": {}, 463 | "source": [ 464 | "
Nota: \n", 465 | "En el caso 1D es válido tanto `np.zeros([5])` como `np.zeros(5)` (sin los corchetes), pero no lo será para el caso nD\n", 466 | "
" 467 | ] 468 | }, 469 | { 470 | "cell_type": "markdown", 471 | "metadata": {}, 472 | "source": [ 473 | "#### array \"vacío\"" 474 | ] 475 | }, 476 | { 477 | "cell_type": "code", 478 | "execution_count": null, 479 | "metadata": { 480 | "collapsed": false 481 | }, 482 | "outputs": [], 483 | "source": [] 484 | }, 485 | { 486 | "cell_type": "markdown", 487 | "metadata": {}, 488 | "source": [ 489 | "
Importante: \n", 490 | "El array vacío se crea en un tiempo algo inferior al array de ceros. Sin embargo, el valor de sus elementos será arbitrario y dependerá del estado de la memoria. Si lo utilizas asegúrate de que luego llenas bien todos sus elementos porque podrías introducir resultados erróneos.\n", 491 | "
" 492 | ] 493 | }, 494 | { 495 | "cell_type": "markdown", 496 | "metadata": {}, 497 | "source": [ 498 | "#### array de unos" 499 | ] 500 | }, 501 | { 502 | "cell_type": "code", 503 | "execution_count": null, 504 | "metadata": { 505 | "collapsed": false 506 | }, 507 | "outputs": [], 508 | "source": [] 509 | }, 510 | { 511 | "cell_type": "markdown", 512 | "metadata": {}, 513 | "source": [ 514 | "
Nota: \n", 515 | "Otras funciones muy útiles son `np.zeros_like` y `np.ones_like`. Usa la ayuda para ver lo que hacen si lo necesitas.\n", 516 | "
" 517 | ] 518 | }, 519 | { 520 | "cell_type": "markdown", 521 | "metadata": {}, 522 | "source": [ 523 | "#### array identidad" 524 | ] 525 | }, 526 | { 527 | "cell_type": "code", 528 | "execution_count": null, 529 | "metadata": { 530 | "collapsed": false 531 | }, 532 | "outputs": [], 533 | "source": [] 534 | }, 535 | { 536 | "cell_type": "markdown", 537 | "metadata": {}, 538 | "source": [ 539 | "
Nota: \n", 540 | "También puedes probar `np.eye()` y `np.diag()`.\n", 541 | "
" 542 | ] 543 | }, 544 | { 545 | "cell_type": "markdown", 546 | "metadata": {}, 547 | "source": [ 548 | "### Rangos" 549 | ] 550 | }, 551 | { 552 | "cell_type": "markdown", 553 | "metadata": {}, 554 | "source": [ 555 | "#### np.arange" 556 | ] 557 | }, 558 | { 559 | "cell_type": "markdown", 560 | "metadata": {}, 561 | "source": [ 562 | "NumPy, dame __un array que vaya de 0 a 5__:" 563 | ] 564 | }, 565 | { 566 | "cell_type": "code", 567 | "execution_count": null, 568 | "metadata": { 569 | "collapsed": false 570 | }, 571 | "outputs": [], 572 | "source": [] 573 | }, 574 | { 575 | "cell_type": "markdown", 576 | "metadata": {}, 577 | "source": [ 578 | "__Mira con atención el resultado anterior__, ¿hay algo que deberías grabar en tu cabeza para simpre?\n", 579 | "__El último elemento no es 5 sino 4__" 580 | ] 581 | }, 582 | { 583 | "cell_type": "markdown", 584 | "metadata": {}, 585 | "source": [ 586 | "NumPy, dame __un array que vaya de 0 a 10, de 3 en 3__:" 587 | ] 588 | }, 589 | { 590 | "cell_type": "code", 591 | "execution_count": null, 592 | "metadata": { 593 | "collapsed": false 594 | }, 595 | "outputs": [], 596 | "source": [] 597 | }, 598 | { 599 | "cell_type": "markdown", 600 | "metadata": {}, 601 | "source": [ 602 | "#### np.linspace" 603 | ] 604 | }, 605 | { 606 | "cell_type": "markdown", 607 | "metadata": {}, 608 | "source": [ 609 | "Si has tenido que usar MATLAB alguna vez, seguro que esto te suena:" 610 | ] 611 | }, 612 | { 613 | "cell_type": "code", 614 | "execution_count": null, 615 | "metadata": { 616 | "collapsed": false 617 | }, 618 | "outputs": [], 619 | "source": [] 620 | }, 621 | { 622 | "cell_type": "markdown", 623 | "metadata": {}, 624 | "source": [ 625 | "En este caso sí que se incluye el último elemento." 626 | ] 627 | }, 628 | { 629 | "cell_type": "markdown", 630 | "metadata": {}, 631 | "source": [ 632 | "
Nota: \n", 633 | "También puedes probar `np.logspace()`\n", 634 | "
" 635 | ] 636 | }, 637 | { 638 | "cell_type": "markdown", 639 | "metadata": {}, 640 | "source": [ 641 | "### reshape" 642 | ] 643 | }, 644 | { 645 | "cell_type": "markdown", 646 | "metadata": {}, 647 | "source": [ 648 | "Con `np.arange()` es posible crear \"vectores\" cuyos elementos tomen valores consecutivos o equiespaciados, como hemos visto anteriormente. ¿Podemos hacer lo mismo con \"matrices\"? Pues sí, pero no usando una sola función. Imagina que quieres crear algo como esto:\n", 649 | "\n", 650 | "\\begin{pmatrix}\n", 651 | " 1 & 2 & 3\\\\ \n", 652 | " 4 & 5 & 6\\\\\n", 653 | " 7 & 8 & 9\\\\\n", 654 | " \\end{pmatrix}\n", 655 | " \n", 656 | "* Comenzaremos por crear un array 1d con los valores $(1,2,3,4,5,6,7,8,9)$ usando `np.arange()`.\n", 657 | "* Luego le daremos forma de array 2d. con `np.reshape(array, (dim0, dim1))`." 658 | ] 659 | }, 660 | { 661 | "cell_type": "code", 662 | "execution_count": null, 663 | "metadata": { 664 | "collapsed": false 665 | }, 666 | "outputs": [], 667 | "source": [] 668 | }, 669 | { 670 | "cell_type": "code", 671 | "execution_count": null, 672 | "metadata": { 673 | "collapsed": false 674 | }, 675 | "outputs": [], 676 | "source": [ 677 | "# También funciona como método\n" 678 | ] 679 | }, 680 | { 681 | "cell_type": "markdown", 682 | "metadata": {}, 683 | "source": [ 684 | "
Nota: \n", 685 | "No vamos a entrar demasiado en qué son los métodos, pero debes saber que están asociados a la programación orientada a objetos y que en Python todo es un objeto. Lo que debes pensar es que son unas funciones especiales en las que el argumento más importante (sobre el que se realiza la acción) se escribe delante seguido de un punto. Por ejemplo: `.método(argumentos)`\n", 686 | "
" 687 | ] 688 | }, 689 | { 690 | "cell_type": "markdown", 691 | "metadata": {}, 692 | "source": [ 693 | "## Importación" 694 | ] 695 | }, 696 | { 697 | "cell_type": "markdown", 698 | "metadata": {}, 699 | "source": [ 700 | "Python es un lenguaje que está altamente modularizado: está dividido en __bibliotecas que realizan tareas específicas__. Para hacer uso de ellas debemos importarlas. Podemos importar cosas de la [biblioteca estándar](https://docs.python.org/3.4/library/), de paquetes que hayamos descargado (o se enceuntren en [nuestra distribución](http://docs.continuum.io/anaconda/pkg-docs.html)) o de módulos que nosotros mismos construyamos. \n", 701 | "\n", 702 | "Existen varias formas de importar:\n", 703 | "\n", 704 | " import numpy\n", 705 | " \n", 706 | "Cada vez que queramos acceder a una función de numpy, deberemos escribir:\n", 707 | " \n", 708 | " numpy.sin(5)\n", 709 | " numpy.linspace(0,100,50)\n", 710 | " \n", 711 | "---\n", 712 | "Como esto puede resultar tedioso, suele utilizarse un __namespace__, el recomendado en la documentación oficial y que usaremos en el curso es:\n", 713 | "\n", 714 | " import numpy as np\n", 715 | " \n", 716 | "Ahora podremos llamar a funciones escribiendo:\n", 717 | "\n", 718 | " np.sin(5)\n", 719 | " np.linspace(0,100,50)\n", 720 | " \n", 721 | "---\n", 722 | "Si esto te sigue pareciendo demasido escribir puedes hacer (__altamente no recomendado__):\n", 723 | "\n", 724 | " from numpy import *\n", 725 | " \n", 726 | "El asterisco, quiere decir _TODO_. Esto genera varios problemas: \n", 727 | "\n", 728 | "* __Imporatará gran cantidad de funciones y clases que puede que no necesites__.\n", 729 | "* El nombre de estas funciones, puede coincidir con el de alguna de otro módulo que hayas importado, de manera que \"la machacará\", por lo que __se producirán ambigüedades__." 730 | ] 731 | }, 732 | { 733 | "cell_type": "markdown", 734 | "metadata": {}, 735 | "source": [ 736 | "##### Ejemplo: ¿por qué no hacer from numpy import * ?" 737 | ] 738 | }, 739 | { 740 | "cell_type": "code", 741 | "execution_count": null, 742 | "metadata": { 743 | "collapsed": false 744 | }, 745 | "outputs": [], 746 | "source": [] 747 | }, 748 | { 749 | "cell_type": "code", 750 | "execution_count": null, 751 | "metadata": { 752 | "collapsed": false 753 | }, 754 | "outputs": [], 755 | "source": [] 756 | }, 757 | { 758 | "cell_type": "markdown", 759 | "metadata": {}, 760 | "source": [ 761 | "__La función seno que incorporá math no es la misma que la de NumPy__. Ambas proporcionarán el seno de un número, evidentemente, el mismo resultado para el mismo número, pero una acepta listas y la otra no. Al hacer la segunda importación, la función seno de NumPy se ha sustituido por la de math y la misma sentencia, da un error. Esto puede hacer que te vuelvas un poco loco si tu código es grande o acabes volviendo loco a alguien si usa tu código.\n", 762 | "\n", 763 | "¿Suficiente? Ahora ya sabes por qué tendrás que escribir `np.loquesea` __siempre__." 764 | ] 765 | }, 766 | { 767 | "cell_type": "markdown", 768 | "metadata": {}, 769 | "source": [ 770 | "
Importante: Reiniciemos el kernel e importemos bien NumPy para continuar.
" 771 | ] 772 | }, 773 | { 774 | "cell_type": "code", 775 | "execution_count": null, 776 | "metadata": { 777 | "collapsed": false 778 | }, 779 | "outputs": [], 780 | "source": [ 781 | "import numpy as np" 782 | ] 783 | }, 784 | { 785 | "cell_type": "markdown", 786 | "metadata": {}, 787 | "source": [ 788 | "## Operaciones" 789 | ] 790 | }, 791 | { 792 | "cell_type": "markdown", 793 | "metadata": {}, 794 | "source": [ 795 | "### Operaciones elemento a elemento" 796 | ] 797 | }, 798 | { 799 | "cell_type": "markdown", 800 | "metadata": {}, 801 | "source": [ 802 | "Ahora que pocas cosas se nos escapan de los arrays, probemos a hacer algunas operaciones. El funcionamiento es el habitual en FORTRAN y MATLAB y poco hay que añadir:" 803 | ] 804 | }, 805 | { 806 | "cell_type": "code", 807 | "execution_count": null, 808 | "metadata": { 809 | "collapsed": false 810 | }, 811 | "outputs": [], 812 | "source": [ 813 | "#crear un array y sumarle un número\n" 814 | ] 815 | }, 816 | { 817 | "cell_type": "code", 818 | "execution_count": null, 819 | "metadata": { 820 | "collapsed": false 821 | }, 822 | "outputs": [], 823 | "source": [ 824 | "#multiplicarlo por un número\n" 825 | ] 826 | }, 827 | { 828 | "cell_type": "code", 829 | "execution_count": null, 830 | "metadata": { 831 | "collapsed": false 832 | }, 833 | "outputs": [], 834 | "source": [ 835 | "#elevarlo al cuadrado\n" 836 | ] 837 | }, 838 | { 839 | "cell_type": "code", 840 | "execution_count": null, 841 | "metadata": { 842 | "collapsed": false 843 | }, 844 | "outputs": [], 845 | "source": [ 846 | "#calcular una función\n" 847 | ] 848 | }, 849 | { 850 | "cell_type": "markdown", 851 | "metadata": {}, 852 | "source": [ 853 | "
Entrenamiento: \n", 854 | "Puedes tratar de comparar la diferencia de tiempo entre realizar la operación en bloque, como ahora, y realizarla elemento a elemento, recorriendo el array con un bucle.\n", 855 | "
" 856 | ] 857 | }, 858 | { 859 | "cell_type": "markdown", 860 | "metadata": {}, 861 | "source": [ 862 | "__Si las operaciones involucran dos arrays también se realizan elemento a elemento__" 863 | ] 864 | }, 865 | { 866 | "cell_type": "code", 867 | "execution_count": null, 868 | "metadata": { 869 | "collapsed": false 870 | }, 871 | "outputs": [], 872 | "source": [ 873 | "#creamos dos arrays\n" 874 | ] 875 | }, 876 | { 877 | "cell_type": "code", 878 | "execution_count": null, 879 | "metadata": { 880 | "collapsed": false 881 | }, 882 | "outputs": [], 883 | "source": [ 884 | "#los sumamos\n" 885 | ] 886 | }, 887 | { 888 | "cell_type": "code", 889 | "execution_count": null, 890 | "metadata": { 891 | "collapsed": false 892 | }, 893 | "outputs": [], 894 | "source": [ 895 | "#multiplicamos\n" 896 | ] 897 | }, 898 | { 899 | "cell_type": "markdown", 900 | "metadata": {}, 901 | "source": [ 902 | "#### Comparaciones" 903 | ] 904 | }, 905 | { 906 | "cell_type": "code", 907 | "execution_count": null, 908 | "metadata": { 909 | "collapsed": false 910 | }, 911 | "outputs": [], 912 | "source": [ 913 | "# >,<\n" 914 | ] 915 | }, 916 | { 917 | "cell_type": "code", 918 | "execution_count": null, 919 | "metadata": { 920 | "collapsed": false 921 | }, 922 | "outputs": [], 923 | "source": [ 924 | "# ==\n" 925 | ] 926 | }, 927 | { 928 | "cell_type": "markdown", 929 | "metadata": {}, 930 | "source": [ 931 | "
Nota: \n", 932 | "Por cierto, ¿qúe ocurrirá si los arrays con los que se quiere operar no tiene la misma forma? ¿apuestas? Quizá más adelante te interese buscar algo de información sobre __broadcasting__.\n", 933 | "
" 934 | ] 935 | }, 936 | { 937 | "cell_type": "markdown", 938 | "metadata": {}, 939 | "source": [ 940 | "## Ejercicios\n", 941 | "\n", 942 | "1. Crear un array z1 3x4 lleno de ceros de tipo entero.\n", 943 | "2. Crear un array z2 3x4 lleno de ceros salvo la primera fila que serán todo unos.\n", 944 | "3. Crear un array z3 3x4 lleno de ceros salvo la última fila que será el rango entre 5 y 8.\n", 945 | "4. Crea un vector de 10 elementos, siendo los impares unos y los pares doses.\n", 946 | "5. Crea un «tablero de ajedrez», con unos en las casillas negras y ceros en las blancas." 947 | ] 948 | }, 949 | { 950 | "cell_type": "markdown", 951 | "metadata": {}, 952 | "source": [ 953 | "---" 954 | ] 955 | }, 956 | { 957 | "cell_type": "markdown", 958 | "metadata": {}, 959 | "source": [ 960 | "___Hemos aprendido:___\n", 961 | "\n", 962 | "* Las características de los arrays de NumPy:\n", 963 | " - Homogeneidad de tipo.\n", 964 | " - Tamaño fijo en el momento de la creación.\n", 965 | "* A usar las principales funciones para crear arrays.\n", 966 | "* A operar con arrays.\n", 967 | "\n", 968 | "_En definitiva:_\n", 969 | "* __Ingenieros y científicos $\\heartsuit$ arrays.__\n", 970 | "* __Ingenieros y científicos necesitan NumPy.__\n", 971 | "\n", 972 | "__El próximo día__ aprenderemos cómo acceder a elementos de un array _slicing_, cómo realizar algunas operaciones de álgebra lineal (determinantes, trazas, autovalores...) y practicaremos todo lo aprendido.\n", 973 | "\n", 974 | "__¡Quiero más!__Algunos enlaces:\n", 975 | "\n", 976 | "Algunos enlaces en Pybonacci:\n", 977 | "\n", 978 | "* [Cómo crear matrices en Python con NumPy](http://pybonacci.wordpress.com/2012/06/11/como-crear-matrices-en-python-con-numpy/).\n", 979 | "* [Números aleatorios en Python con NumPy y SciPy](http://pybonacci.wordpress.com/2013/01/11/numeros-aleatorios-en-python-con-numpy-y-scipy/).\n", 980 | "\n", 981 | "\n", 982 | "Algunos enlaces en otros sitios:\n", 983 | "\n", 984 | "* [100 numpy exercises](http://www.labri.fr/perso/nrougier/teaching/numpy.100/index.html). Es posible que de momento sólo sepas hacer los primeros, pero tranquilo, pronto sabrás más...\n", 985 | "* [NumPy and IPython SciPy 2013 Tutorial](http://conference.scipy.org/scipy2013/tutorial_detail.php?id=100).\n", 986 | "* [NumPy and SciPy documentation](http://docs.scipy.org/doc/)." 987 | ] 988 | }, 989 | { 990 | "cell_type": "markdown", 991 | "metadata": {}, 992 | "source": [ 993 | "---\n", 994 | "\n", 995 | "Clase en vídeo, parte del [Curso de Python para científicos e ingenieros](http://cacheme.org/curso-online-python-cientifico-ingenieros/) grabado en la Escuela Politécnica Superior de la Universidad de Alicante." 996 | ] 997 | }, 998 | { 999 | "cell_type": "code", 1000 | "execution_count": 1, 1001 | "metadata": { 1002 | "collapsed": false 1003 | }, 1004 | "outputs": [ 1005 | { 1006 | "data": { 1007 | "text/html": [ 1008 | "\n", 1009 | " \n", 1016 | " " 1017 | ], 1018 | "text/plain": [ 1019 | "" 1020 | ] 1021 | }, 1022 | "execution_count": 1, 1023 | "metadata": {}, 1024 | "output_type": "execute_result" 1025 | } 1026 | ], 1027 | "source": [ 1028 | "from IPython.display import YouTubeVideo\n", 1029 | "\n", 1030 | "YouTubeVideo(\"UltVlYCacD0\", width=560, height=315, list=\"PLGBbVX_WvN7bMwYe7wWV5TZt1a58jTggB\")" 1031 | ] 1032 | }, 1033 | { 1034 | "cell_type": "markdown", 1035 | "metadata": {}, 1036 | "source": [ 1037 | "---" 1038 | ] 1039 | }, 1040 | { 1041 | "cell_type": "markdown", 1042 | "metadata": {}, 1043 | "source": [ 1044 | "Si te ha gustado esta clase:\n", 1045 | "\n", 1046 | "Tweet\n", 1047 | "\n", 1048 | "\n", 1049 | "---" 1050 | ] 1051 | }, 1052 | { 1053 | "cell_type": "markdown", 1054 | "metadata": {}, 1055 | "source": [ 1056 | "####

¡Síguenos en Twitter!" 1057 | ] 1058 | }, 1059 | { 1060 | "cell_type": "markdown", 1061 | "metadata": {}, 1062 | "source": [ 1063 | "###### Follow @AeroPython " 1064 | ] 1065 | }, 1066 | { 1067 | "cell_type": "markdown", 1068 | "metadata": {}, 1069 | "source": [ 1070 | "##### \"Licencia
Curso AeroPython por Juan Luis Cano Rodriguez y Alejandro Sáez Mollejo se distribuye bajo una Licencia Creative Commons Atribución 4.0 Internacional." 1071 | ] 1072 | }, 1073 | { 1074 | "cell_type": "markdown", 1075 | "metadata": {}, 1076 | "source": [ 1077 | "##### " 1078 | ] 1079 | }, 1080 | { 1081 | "cell_type": "markdown", 1082 | "metadata": {}, 1083 | "source": [ 1084 | "---\n", 1085 | "_Las siguientes celdas contienen configuración del Notebook_\n", 1086 | "\n", 1087 | "_Para visualizar y utlizar los enlaces a Twitter el notebook debe ejecutarse como [seguro](http://ipython.org/ipython-doc/dev/notebook/security.html)_\n", 1088 | "\n", 1089 | " File > Trusted Notebook" 1090 | ] 1091 | }, 1092 | { 1093 | "cell_type": "code", 1094 | "execution_count": 1, 1095 | "metadata": { 1096 | "collapsed": false 1097 | }, 1098 | "outputs": [ 1099 | { 1100 | "data": { 1101 | "text/html": [ 1102 | "Follow @AeroPython\n", 1103 | "" 1104 | ], 1105 | "text/plain": [ 1106 | "" 1107 | ] 1108 | }, 1109 | "metadata": {}, 1110 | "output_type": "display_data" 1111 | } 1112 | ], 1113 | "source": [ 1114 | "%%html\n", 1115 | "Follow @AeroPython\n", 1116 | "" 1117 | ] 1118 | }, 1119 | { 1120 | "cell_type": "code", 1121 | "execution_count": 2, 1122 | "metadata": { 1123 | "collapsed": false 1124 | }, 1125 | "outputs": [ 1126 | { 1127 | "data": { 1128 | "text/html": [ 1129 | "\n", 1130 | "\n", 1131 | "El estilo se ha aplicado =)\n", 1132 | "\n", 1133 | "\n", 1270 | "\n" 1286 | ], 1287 | "text/plain": [ 1288 | "" 1289 | ] 1290 | }, 1291 | "execution_count": 2, 1292 | "metadata": {}, 1293 | "output_type": "execute_result" 1294 | } 1295 | ], 1296 | "source": [ 1297 | "# Esta celda da el estilo al notebook\n", 1298 | "from IPython.core.display import HTML\n", 1299 | "css_file = '../static/styles/style.css'\n", 1300 | "HTML(open(css_file, \"r\").read())" 1301 | ] 1302 | } 1303 | ], 1304 | "metadata": { 1305 | "kernelspec": { 1306 | "display_name": "Python 3", 1307 | "language": "python", 1308 | "name": "python3" 1309 | }, 1310 | "language_info": { 1311 | "codemirror_mode": { 1312 | "name": "ipython", 1313 | "version": 3 1314 | }, 1315 | "file_extension": ".py", 1316 | "mimetype": "text/x-python", 1317 | "name": "python", 1318 | "nbconvert_exporter": "python", 1319 | "pygments_lexer": "ipython3", 1320 | "version": "3.4.3" 1321 | } 1322 | }, 1323 | "nbformat": 4, 1324 | "nbformat_minor": 0 1325 | } 1326 | --------------------------------------------------------------------------------