{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tipos compósitos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Modelar una partícula:\n", "\n", "Yo estaba esperando" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.5" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 1\n", "v = 2\n", "m = 0.5" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1.25" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dt = 0.125\n", "x += v*dt" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x2 = 2\n", "v2 = 10" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "N = 10 # numero de particulas" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [], "source": [ "x = zeros(N)\n", "v = ones(N);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Muchos hicieron" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3-element Array{Float64,1}:\n", " 1.0\n", " 2.0\n", " 0.5" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "particula = [1, 2, 0.5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La posición es" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "particula[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para actualizar su posición:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1.5" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "particula[1] += dt*particula[2]\n", "# equivalente a particula[1] = particula[1] + dt*particula[2]\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "¡Es illegible! Queremos nombres que *reflejen* la función de cada variable: `x` y `v`, o `pos`y `vel`, o `posicion` y `velocidad`\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Tipos compósitos " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Es la solución: combinación de variables con nombres, adentro de una sola estructura." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": true }, "outputs": [], "source": [ "type Particula\n", " x\n", " v\n", " m\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Aquí estamos definiendo un nuevo *tipo* de datos, que se llama `Particula`, y especificamos las características / propiedades internas de lo que es una `Particula` -- la estructura de una `Particula`.\n", "\n", "Define una *plantilla* de una cajita que contiene espacio para estas tres variables (`x`, `v` y `m`)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "¡Todavía no hay ninguna partícula! Para crear un objeto de este tipo (`Particula`): Utilizo `Particula` como si fuera una función:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Particula(1.0,2.0,0.5)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p = Particula(1., 2., 0.5)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Particula(1.0,2.0,0.5)" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.x" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2.0" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.v" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.5" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.m" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Particula (constructor with 1 method)" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "typeof(p)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Funciones que actúan sobre objetos de este tipo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Quiero definir una función `mover` que acepte un objeto de tipo `Particula`:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "mover (generic function with 1 method)" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function mover(p, dt)\n", " p.x + p.v*dt\n", "end" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Particula(1.0,2.0,0.5)" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1.2" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mover(p, 0.1)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Particula(1.0,2.0,0.5)" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "¡No se movió! Sólo se calculó la posición nueva.\n", "Para mover realmente el objeto, tenemos que cambiar sus propiedades internas:" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "mover! (generic function with 1 method)" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function mover!(p, dt) \n", " # ! es una convención en Julia que dice que la función\n", " # *modifica* su argumento -- tiene un *efecto secundario* (side effect)\n", " p.x += p.v*dt\n", "end" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3.0" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mover!(p, 1)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Particula(3.0,2.0,0.5)" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "No llamé a la función `mover_particula`" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [ { "ename": "LoadError", "evalue": "type Int64 has no field x\nwhile loading In[27], in expression starting on line 1", "output_type": "error", "traceback": [ "type Int64 has no field x\nwhile loading In[27], in expression starting on line 1", "", " in mover! at In[24]:4" ] } ], "source": [ "mover!(1, 0.1)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": true }, "outputs": [], "source": [ "workspace() # borra todo lo que está definido" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [], "source": [ "type Prueba\n", " x\n", " v\n", " David\n", "end" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "ename": "LoadError", "evalue": "Particula not defined\nwhile loading In[32], in expression starting on line 1", "output_type": "error", "traceback": [ "Particula not defined\nwhile loading In[32], in expression starting on line 1", "" ] } ], "source": [ "p = Particula(1,2,3) # borré la definición" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "mover! (generic function with 1 method)" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function mover!(p, dt) \n", " # ! es una convención en Julia que dice que la función\n", " # *modifica* su argumento -- tiene un *efecto secundario* (side effect)\n", " p.x += p.v*dt\n", "end" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Prueba(1,2,3)" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d = Prueba(1, 2, 3)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1.2" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mover!(d, 0.1)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Prueba(1.2,2,3)" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mi función como tal mueve *cualquier cosa* que tenga un `x` y `v` adentro. Si no quiero esto:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": true }, "outputs": [], "source": [ "type Particula\n", " x::Float64 # sólo puede ser de tipo Float64 \n", " v\n", " m\n", "end" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "mover! (generic function with 2 methods)" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function mover!(p::Particula, dt) \n", " # sólo actúa sobre objetos de tipo Particula\n", " p.x += p.v*dt\n", "end" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Particula(1.0,2,0.5)" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p = Particula(1, 2, 0.5)\n" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1.2" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mover!(p, 0.1)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Particula(1.2,2,0.5)" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "2 methods for generic function mover!: