4.0 - Funciones: ¿qué son? | Semana 4.
JAP 2023
En esta sección se introduce el concepto de funciones en la programación y se explica
cómo pueden ser útiles para dividir el trabajo de un programa en tareas más pequeñas y
separadas de la parte principal. Para ilustrar esto, se presenta un ejemplo de una
calculadora que debe implementar la multiplicación a partir de la suma.
Para realizar la multiplicación de a * b a partir de la suma, se puede utilizar el siguiente
algoritmo:
Inicializar el contador en 1.
Inicializar el resultado con el valor de a.
Mientras el contador sea menor que b: 3.1. Sumar a al resultado. 3.2. Incrementar el
contador en 1. Fin del ciclo.
Mostrar el valor de resultado.
Sin embargo, si se desea agregar la operación de potencia a la calculadora, es decir, un
número a elevado a la b (ab), se debe multiplicar a * a, b veces. En este caso, se podría
duplicar el código de la multiplicación en el programa principal y utilizarlo tanto para la
multiplicación como para la exponenciación.
Sin embargo, esto presenta dos desventajas: en primer lugar, se estaría duplicando código,
lo que podría hacer que el programa principal sea muy extenso si se tienen más
operaciones que se utilizan en distintas partes del programa. En segundo lugar, si se decide
mejorar el algoritmo, se tendría que modificar en varias partes del programa donde se utiliza
el mismo código.
Es aquí donde las funciones tienen un uso sustancial para mejorar la aplicación. Se pueden
apartar las líneas de código que realizan la multiplicación entre dos números, etiquetarlas
con un nombre y hacer uso de ellas desde cualquier parte del programa principal,
invocándolas a partir del nombre.
Por ejemplo, se podría crear una función llamada "multiplicar" que acepta dos parámetros
de entrada (los números a multiplicar), ejecuta el algoritmo de multiplicación con esos
números de entrada y retorna el resultado. De esta manera, se evita duplicar código y se
puede utilizar la misma función en cualquier parte del programa donde se necesite realizar
una multiplicación. Además, si se desea mejorar el algoritmo, solo se tendría que modificar
la función "multiplicar" en lugar de modificar el código en varias partes del programa.
2 - Estructura general
En la sección 2 de 2 se explica la estructura general de las funciones en la programación, la
cual puede variar levemente entre un lenguaje de programación y otro. En esta sección se
trabajará con una sintaxis genérica.
La estructura de una función se compone de los siguientes elementos:
tipo_retorno: indica el tipo de datos que retornará la función. Por ejemplo, si la función
realiza la multiplicación de dos números, retornará el tipo de datos numérico (sea entero o
real), ya que devolverá el resultado de dicha multiplicación. Este elemento es opcional en
algunos lenguajes de programación, como JavaScript.
function: es una palabra reservada que indica que se está definiendo una función. Esta
palabra depende del lenguaje de programación, en el caso de Gobstones y JavaScript es
"function".
nombre_funcion: aquí se indica el nombre que tendrá la función, del cual luego se hará uso
para invocar a la misma. Es una buena práctica que el nombre describa el objetivo de la
función, por ejemplo, si se está realizando la multiplicación entre dos números, será intuitivo
que la función se llame "multiplicar".
argumentos: cuando se necesita que la función reciba datos a ser calculados (no siempre
es necesario, por eso es opcional), se los indica dentro de los paréntesis a continuación (sin
espacios) del nombre. A estos datos se los denomina argumentos o parámetros de entrada.
bloque_código: aquí es donde se indican las líneas de código a ser ejecutadas por la
función.
Los argumentos de una función, también llamados parámetros, representan una lista de
variables cuyos valores son pasados a la función para ser usados por esta. Suelen ser
opcionales, por eso en el ejemplo están en corchetes []. Algunas funciones no aceptan
argumentos.
El código de la función es la secuencia de instrucciones o sentencias que la función realiza.
Estas instrucciones son las tareas que hacen que la función tenga sentido. Para saber que
un bloque de código pertenece a una función, en el ejemplo está entre llaves {}. Así se sabe
cuando acaba la función. En algunos lenguajes se puede encontrar otra manera de indicar
cuando empieza y termina una función, por ejemplo, con las palabras "Begin" y "End",
aunque en la mayoría se hace uso de las llaves {}.
Las pautas para hacer una llamada a una función son:
No hay límite en cuanto a la cantidad de llamadas a funciones que se puede realizar.
Se puede invocar a las funciones en cualquier orden.
Cuando se invoca a una función, los argumentos que se le pasan deben respetar el orden
que tienen en la declaración. Por ejemplo, si se declara una función (a, b), cuando es
invocada, no se debe invertir los parámetros de forma función (b,a).
El retorno de una función es el resultado de los cálculos realizados por la misma, es decir, el
objetivo alcanzado de la misma. En el ejemplo planteado en la introducción, se define la
función "multiplicar" con los parámetros de entrada "a" y "b", necesarios para realizar la
multiplicación. Se hace uso de la palabra reservada "function" y se define el bloque de
código que realiza la multiplicación.
Para invocar la función, se puede utilizar el ejemplo de una calculadora que desea realizar
la multiplicación o la exponenciación de dos números. En el caso de la exponenciación, se
hace uso de la función "multiplicar" para hallar el resultado de num1^num2. Por ejemplo:
program {
1. si el usuario desea multiplicar:
1. num1 = ingresar número
2. num2 = ingresar número
3. resultado a mostrar = multiplicar(num1, num2)
2. si el usuario desea exponenciar:
se hace uso de la función multiplicar para hallar el resultado de num1^num2:
1. inicializar contador en 1
2. inicializar resultado con valor de num1
3. mientras (contador < num2)
3.1 resultado = multiplicar(resultado, num1)
3.2 contador = contador + 1
fin mientras
}
En este ejemplo, se utiliza la función "multiplicar" para realizar la exponenciación de dos
números. Se inicializa un contador en 1 y se inicializa el resultado con el valor de num1.
Luego, se realiza un ciclo mientras el contador sea menor que num2, en el cual se llama a
la función "multiplicar" para multiplicar el resultado por num1 y se incrementa el contador en
1. Al finalizar el ciclo, se obtiene el resultado de la exponenciación.
Selecciona todas las afirmaciones que consideres correctas:
A - Al momento de definir una función, debemos especificar al menos un argumento.
B - El código de una función debería ser lo más simple posible, sin complejizar ni abarcar
una gran cantidad de tareas/cálculos a realizar dentro de ella.
C - Una de las principales ventajas de las funciones, es que nos ayuda a evitar código
duplicado, ya que para la misma tarea que necesitemos ejecutar en múltiples situaciones,
podemos hacer siempre uso de la función definida una única vez.
D - Al momento de invocar una función, la estaremos definiendo
B y C son afirmaciones correctas.
A es incorrecta, ya que no siempre es necesario especificar argumentos al definir una
función.
D es incorrecta, ya que al invocar una función simplemente estamos llamando a la función
previamente definida para que ejecute su código. No estamos definiendo la función en ese
momento.
Cuestionario: Al definir una función en Gobstones y JavaScript utilizando la palabra
reservada "function" seguido de un nombre de función, es necesario incluir los
paréntesis curvos después del nombre de la función, incluso si la función no recibe
argumentos.
En la mayoría de los lenguajes de programación, se utiliza el uso de llaves {} para
indicar que un bloque de código pertenece a una función. Sin embargo, en algunos
lenguajes de programación como Pascal, se utiliza la palabra reservada "begin" para
indicar el inicio del bloque de código de la función y la palabra reservada "end" para
indicar el final del bloque de código de la función.
Una función matemática es un ejemplo común de una función en programación. En
matemáticas, una función es una relación entre un conjunto de entradas
(argumentos o parámetros de entrada) y un conjunto de salidas (resultado o valor de
la función). En programación, una función es similar en el sentido de que toma uno o
más argumentos como entrada y produce un resultado como salida. Por ejemplo, la
función matemática "f(x) = x^2" toma un valor "x" como entrada y produce como
salida el valor "x^2". En programación, se podría definir una función "cuadrado" que
toma un número como argumento y devuelve el cuadrado de ese número como
resultado.
Generalmente en los lenguajes de programación, se debe especificar el tipo de datos de
retorno que devolverá una función definida (incluyendo JavaScript). (FALSO)
VIDEO: Programación imperativa Funciones.
[Link]. El punto “log” es un método. Una funcion es un método que devuelve algo; lo
que sea. Un procedimiento, por más que lo llame, no devuelve nada.
Cuando quiero que retorne la función, agrego “Return”.
La “firma de la función” es lo que yace dentro de ().
JS es un lenguaje de programación débilmente tipado. El tema de los tipos de datos, definir
los tipos de datos, no es tan estricto a diferencia de otros lenguajes fuerte tipados que es
muy importante definir el tipo de datos y cómo se realizan las operaciones.
Estructura de bifurcación: If.(Si). Else(de lo contrario).
El if tiene entre () la condición. LSi es verdadero va entre llaves lo que queremos que haga.
Si no es así, else, llaves y dentro de ellas lo que queremos que se haga si la condición del if
es falsa.
Al invocar la función, hay que tener cuidado cual es el tipo de dato colocado como
argumento al momento de llamar la función(si colocamos algo que no es lo que se espera
nos devolverá error o que no está definido aquello que colocamos).
Si colocamos ‘a’(string) como argumento pero en nuestro if la condición === (DATO TYPE
NUMBER) no nos devolverá un error, mas si el return. Esto porque JS es un lenguaje
débilmente tipado, en otro no pasa(fuertes tipados).
VIDEO: Programación imperativa Operadores.
operador de asignación: =
variables de tipo string, boolean, number, etc.
Los comentarios que no se ejecutan.
operadores aritmeticos basicos: +, - *, / ++, –
==, !=, <, <=, >, >=
&&, ||, !
++ incrementa en uno la variable y – decrementa en uno
++ o –adelante. primero incrementa y despues muestra la variable incrementada.
let == (dato). Si es igual devuelve true y si no, false.
!= no es igual o distinto.
> mayor, >= mayor e igual, < menor, <= menor igual.
&&: operador lógico y, conjunción lógica
||: operador lógico ||
!: operador lógico not
Estas condiciones simples o complejas las usaremos en los ifs cuando queremos que se
cumpla tal o tal condición en estructuras de repetición.
Podemos ir chequeando en consola de a poco para ir testeando si va andando
correctamente.
Operadores aritméticos:
Suma (+): 5 + 3 // Resultado: 8
Resta (-): 5 - 3 // Resultado: 2
Multiplicación (*): 5 * 3 // Resultado: 15
División (/): 9 / 3 // Resultado: 3
Módulo (%): 7 % 3 // Resultado: 1
Incremento (++): let a = 5; a++ // a ahora es 6
Decremento (--): let b = 5; b-- // b ahora es 4
Operadores de asignación:
Asignación (=): let x = 10
Asignación de suma (+=): x += 5 // x ahora es 15
Asignación de resta (-=): x -= 5 // x ahora es 5
Asignación de multiplicación (*=): x *= 2 // x ahora es 20
Asignación de división (/=): x /= 2 // x ahora es 5
Asignación de módulo (%=): x %= 3 // x ahora es 2
Operadores de comparación:
Igual (==): 5 == '5' // Resultado: true
No igual (!=): 5 != '5' // Resultado: false
Estrictamente igual (===): 5 === '5' // Resultado: false
Estrictamente no igual (!==): 5 !== '5' // Resultado: true
Mayor que (>): 5 > 3 // Resultado: true
Menor que (<): 5 < 3 // Resultado: false
Mayor o igual que (>=): 5 >= 5 // Resultado: true
Menor o igual que (<=): 5 <= 3 // Resultado: false
Operadores lógicos:
AND (&&): true && false // Resultado: false
OR (||): true || false // Resultado: true
NOT (!): !true // Resultado: false
Operadores de bits (bitwise):
AND (&): 5 & 3 // Resultado: 1
OR (|): 5 | 3 // Resultado: 7
XOR (^): 5 ^ 3 // Resultado: 6
NOT (~): ~5 // Resultado: -6
Desplazamiento a la izquierda (<<): 5 << 1 // Resultado: 10
Desplazamiento a la derecha (>>): 5 >> 1 // Resultado: 2
Desplazamiento a la derecha sin signo (>>>): -5 >>> 1 // Resultado: 2147483645
Operadores de tipo:
typeof: typeof 'Hola' // Resultado: 'string'
instanceof: [] instanceof Array // Resultado: true
Operador ternario (condicional):
5 > 3 ? 'Mayor' : 'Menor' // Resultado: 'Mayor'
Además de los operadores que mencioné anteriormente, en programación también existen
otros tipos de operadores, como los operadores de cadena, los operadores de
comparación de tipo, los operadores de condicional ternario, entre otros. A
continuación, te proporciono una breve descripción de cada uno de ellos:
- Operadores de cadena: se utilizan para concatenar cadenas de texto. En JavaScript, el
operador de concatenación es el signo más (+). Por ejemplo: `"Hola " + "mundo"` devuelve
`"Hola mundo"`.
- Operadores de comparación de tipo: se utilizan para comparar el tipo de dos valores.
En JavaScript, el operador de comparación de tipo es el operador `typeof`. Por ejemplo:
`typeof "Hola"` devuelve `"string"`.
- Operadores de coma: se utilizan para separar expresiones en una sola línea de código.
En JavaScript, el operador de coma es el signo de coma (,). Por ejemplo: `let a = 1, b = 2, c
= 3;` define tres variables en una sola línea.
- Operador de condicional ternario: se utiliza para asignar un valor a una variable en
función de una condición. En JavaScript, el operador ternario es el signo de interrogación
seguido de dos puntos (? :). Por ejemplo: `let edad = 18; let mensaje = (edad >= 18) ? "Eres
mayor de edad" : "Eres menor de edad";` asigna el mensaje "Eres mayor de edad" a la
variable `mensaje` si la variable `edad` es mayor o igual a 18, y asigna el mensaje "Eres
menor de edad" en caso contrario.
En cuanto a la programación imperativa, es un paradigma de programación que se
centra en describir cómo se debe realizar una tarea. En la programación imperativa, se
utilizan instrucciones que modifican el estado del programa, es decir, que cambian el valor
de las variables y los datos almacenados en la memoria. El programador debe especificar
paso a paso cómo se debe realizar la tarea, utilizando estructuras de control de flujo como
bucles y condicionales.
Un ejemplo de programación imperativa sería un programa que calcula la suma de los
primeros 10 números naturales. En este caso, el programador debe especificar paso a paso
cómo se debe realizar la tarea, utilizando un bucle para sumar los números y una variable
para almacenar el resultado:
```
let suma = 0;
for (let i = 1; i <= 10; i++) {
suma += i;
}
[Link](suma); // Imprime 55
```
En este ejemplo, el programa utiliza un bucle `for` para sumar los números del 1 al 10, y una
variable `suma` para almacenar el resultado. El programador debe especificar paso a paso
cómo se debe realizar la tarea, utilizando instrucciones que modifican el estado del
programa.
VIDEO: Programación imperativa Funciones Varios Parámetros. Semana 4.3.1
Así como en las variables, los nombres de las variables tienen que ser nemotécnicos.
A la parte superior de una funci+on se le llama “firma”
La función es un método que siempre retorna algo. Si no tiene un “return”, es un
procedimiento.
Los parámetros serán los valores que voy a necesitar para que esa función funcione
correctamente. Les pasaré esos parámetros(argumentos) cuando invoque la función.
VIDEO: Programación imperativa Arreglos
Arreglos(arrays). Hay en una estructura en memoria que arma una colección de datos en
memoria. Esa colección de datos se llama arreglo. Este arreglo tiene una manera especifica
de como se recorre ese arreglo y de cómo funciona.
let edades = [23, 33, 33 ,33] === Esto es un arreglo con datos númericos.
Esto es una estructura, un espacio de memoria con los siguientes datos contenidos dentro
de un arreglo que a su vez es contenido dentro de una variable.
Los arreglos pueden tener diferentes elementos.
Los elementos dentro de un array se encuentran posicionados(índice). Lo particular aqui es
que el primero elemento no será el tomado como “índice” 1, si no que será tomado cómo
Índice 0, el siguiente elemento en el índice 1, y así sucesivamente.
Esto es importante, por ejemplo y entre otras cosas. a la hora de recorrer el arreglo.
El total de los elementos !== al posicionamiento de los mismos.
Accedo al elemento de un arreglo colocando el nombre del array y entre [] la posición del
elemento dentro del array.
VIDEO: Programación imperativa Recorrida de Arreglos.
Arreglo === Vector
Un Vector es una variable alojada dentro de un espacio de memoria. Colección de datos
ordenada, secuenciada. Identifico un array porque, para crearlos, se usan []. Al final
ponerles ;
Si al tratar de localizar uno de los elementos del array me paso del índice en el llamado, me
va a decir “Undefined”, puesto que esa posición no existe, no está ocupada por ningún
elemento del array.
“Function” es la palabra reservada para crear una función en JS.
En un bucle for, primero defino una variable de paso. coloco la condicion que tiene que ser
true para que se ejecute lo que coloque, y, después que se haya ejecutado lo que puse que
se tenía que hacer si eso era true, incrementa la variabilidad o decrementa o lo que
nosotros hayamos puesto en esa variable de paso.
El código corre de arriba hacia abajo.
Una precondición es una condición que se tiene que cumplir antes de realizar tal cosa.
Modularización y Lógica Booleana
La modularización es una técnica fundamental en la programación que nos permite dividir
un problema en problemas más pequeños y resolverlos de manera más eficiente y efectiva.
Para encarar un problema, es necesario subdividirlo en problemas más pequeños, o sea,
modelizarlo. Para esto, es necesario analizar el problema y reconocer patrones, o sea,
acciones que podemos repetir una y otra vez para de esta forma movilizar bien un módulo.
Un módulo, por definición, es una parte que se toma como menor medida convencional, que
es una fracción de un todo, una fracción de un sistema. El concepto no es netamente
informático, si vamos al caso, podemos ver que tenemos los módulos Lego, que son los
ladrillitos que podemos agrupar una encima de otro para formar una estructura, como una
torre o un castillo. En informática, los módulos nos permiten identificar elementos del
sistema que podemos reutilizar y que vamos a repetir, reduciendo así la complejidad del
problema.
La modularización nos ayuda a evitar duplicar código, escribir código una vez y reutilizarlo, y
a aislar los efectos de los cambios. Si tenemos que hacer un cambio, lo cambiamos en el
módulo en el que lo escribimos y listo. También promovemos la reutilización de código y
podemos ocultar detalles de implementación de cómo se implementó algo.
En informática, la modularización se puede hacer en dos formas: funciones o subprocesos.
Los lenguajes de programación tienen módulos en funciones y procedimientos. La
diferencia entre uno y otro es que una función me devuelve un valor siempre, mientras que
un subproceso no.
La modularización nos ayuda a localizar rápidamente el problema de nuestro código y a
solamente arreglar el módulo que esté fallando, en lugar de tener que recorrernos todo el
código para encontrar el error. Además, la modularización nos permite reutilizar código y
hacer la codificación más fácil y eficiente. También podemos acceder a bibliotecas de
funciones ya existentes en diferentes lenguajes de programación para ahorrar tiempo y
esfuerzo en la codificación.
En resumen, la modularización es una técnica fundamental en la programación que nos
permite dividir un problema en problemas más pequeños y resolverlos de manera más
eficiente y efectiva. La modularización nos ayuda a evitar duplicar código, aislar los efectos
de los cambios, promover la reutilización de código, ocultar detalles de implementación,
localizar rápidamente el problema de nuestro código y hacer la codificación más fácil y
eficiente.
La modularización en la programación se puede ilustrar con ejemplos prácticos. A
continuación, se presentan algunos ejemplos en JavaScript y se agrega información
adicional relacionada con los dos textos largos proporcionados anteriormente.
Ejemplo 1: Cálculo de impuestos
Supongamos que estamos desarrollando un programa para calcular impuestos en función
de los ingresos de una persona. Podemos dividir este problema en dos módulos: uno para
calcular el impuesto y otro para mostrar el resultado en un formato específico.
Función de cálculo de impuestos:
```javascript
function calculoImpuesto(ingreso, tasa) {
return ingreso * tasa;
}
```
Función para mostrar el resultado:
```javascript
function mostrarResultado(nombre, impuesto) {
[Link](`${nombre} debe pagar $${impuesto} de impuestos.`);
}
```
Algoritmo principal:
```javascript
const nombre = prompt("Dime tu nombre: ");
const ingreso = parseFloat(prompt("Ingresa tu ingreso: "));
const tasa = 0.15;
const impuesto = calculoImpuesto(ingreso, tasa);
mostrarResultado(nombre, impuesto);
```
En este ejemplo, hemos dividido el problema en dos funciones: `calculoImpuesto` y
`mostrarResultado`. Esto nos permite reutilizar estas funciones en diferentes partes del
código y facilita el mantenimiento del programa.
Ejemplo 2: Conversión de unidades
Imagina que estamos creando un programa para convertir unidades de medida, como
kilómetros a millas y viceversa. Podemos crear funciones para realizar estas conversiones y
luego utilizarlas en nuestro programa principal.
Función para convertir kilómetros a millas:
```javascript
function kmAMillas(km) {
return km * 0.621371;
}
```
Función para convertir millas a kilómetros:
```javascript
function millasAKm(millas) {
return millas / 0.621371;
}
```
Algoritmo principal:
```javascript
const distanciaKm = parseFloat(prompt("Ingresa la distancia en kilómetros: "));
const distanciaMillas = kmAMillas(distanciaKm);
[Link](`La distancia en millas es: ${distanciaMillas}`);
const distanciaMillas = parseFloat(prompt("Ingresa la distancia en millas: "));
const distanciaKm = millasAKm(distanciaMillas);
[Link](`La distancia en kilómetros es: ${distanciaKm}`);
```
En este caso, hemos creado dos funciones para convertir unidades de medida y las hemos
utilizado en el algoritmo principal. Esto nos permite mantener nuestro código organizado y
fácil de entender.
Estos ejemplos demuestran cómo la modularización nos permite dividir problemas
complejos en partes más pequeñas y manejables. Al hacerlo, podemos reutilizar código,
facilitar el mantenimiento y mejorar la legibilidad de nuestro programa. Además, podemos
aprovechar bibliotecas de funciones existentes en diferentes lenguajes de programación
para ahorrar tiempo y esfuerzo en la codificación.
Mis disculpas por la confusión. A continuación, se presentan ejemplos más profundos y
claros basados en los textos proporcionados anteriormente, tanto en JavaScript como en
PSEInt.
Ejemplo 1: Cálculo de área y perímetro de un rectángulo
Supongamos que estamos desarrollando un programa para calcular el área y el perímetro
de un rectángulo. Podemos dividir este problema en dos módulos: uno para calcular el área
y otro para calcular el perímetro.
JavaScript:
```javascript
function calcularArea(ancho, largo) {
return ancho * largo;
}
function calcularPerimetro(ancho, largo) {
return 2 * (ancho + largo);
}
const ancho = parseFloat(prompt("Ingresa el ancho del rectángulo: "));
const largo = parseFloat(prompt("Ingresa el largo del rectángulo: "));
const area = calcularArea(ancho, largo);
const perimetro = calcularPerimetro(ancho, largo);
[Link](`El área del rectángulo es: ${area}`);
[Link](`El perímetro del rectángulo es: ${perimetro}`);
```
PSEInt:
```
Proceso CalcularArea
Dimension ancho, largo
Escribir "Ingresa el ancho del rectángulo: "
Leer ancho
Escribir "Ingresa el largo del rectángulo: "
Leer largo
area <- ancho * largo
Escribir "El área del rectángulo es: ", area
FinProceso
Proceso CalcularPerimetro
Dimension ancho, largo
Escribir "Ingresa el ancho del rectángulo: "
Leer ancho
Escribir "Ingresa el largo del rectángulo: "
Leer largo
perimetro <- 2 * (ancho + largo)
Escribir "El perímetro del rectángulo es: ", perimetro
FinProceso
Proceso Principal
CalcularArea
CalcularPerimetro
FinProceso
```
Ejemplo 2: Cálculo de factorial
Supongamos que estamos desarrollando un programa para calcular el factorial de un
número. Podemos dividir este problema en un módulo para calcular el factorial.
JavaScript:
```javascript
function calcularFactorial(n) {
let factorial = 1;
for (let i = 1; i <= n; i++) {
factorial *= i;
}
return factorial;
}
const numero = parseInt(prompt("Ingresa un número para calcular su factorial: "));
const resultado = calcularFactorial(numero);
[Link](`El factorial de ${numero} es: ${resultado}`);
```
PSEInt:
```
Funcion calcularFactorial(n)
Dimension factorial, i
factorial <- 1
Para i <- 1 Hasta n Con Paso 1 Hacer
factorial <- factorial * i
FinPara
Retornar factorial
FinFuncion
Proceso Principal
Dimension numero, resultado
Escribir "Ingresa un número para calcular su factorial: "
Leer numero
resultado <- calcularFactorial(numero)
Escribir "El factorial de ", numero, " es: ", resultado
FinProceso
```
En estos ejemplos, hemos dividido los problemas en módulos (calcular área y perímetro en
el primer ejemplo, y calcular factorial en el segundo ejemplo). Esto nos permite reutilizar
estas funciones en diferentes partes del código y facilita el mantenimiento del programa.
Además, mejora la legibilidad y la organización del código.
Algebra de Bool
1. Verdadero/Falso: Falso. Las funciones en JavaScript no siempre deben recibir
parámetros, ya que pueden ser funciones que no requieren de entrada.
2. Verdadero/Falso: Verdadero. La modularización es una técnica utilizada en Pensamiento
Computacional para dividir un problema en sub-problemas más pequeños y manejables.
3. Verdadero/Falso: Verdadero. Las funciones en JavaScript deben tener una única tarea u
objetivo a cumplir y ser independientes de cualquier otro código que se encuentre fuera de
ellas para mejorar la legibilidad y la reutilización del código.
4. Verdadero/Falso: Verdadero. El orden de precedencia es el orden en que los operadores
se evalúan en una expresión. Si no hay paréntesis, se evalúa de izquierda a derecha.
5. Verdadero/Falso: Falso. En JavaScript es posible llevar a la práctica el concepto de
módulos utilizando diferentes técnicas, como el uso de funciones como una aproximación, o
utilizando módulos de terceros.
6. Verdadero/Falso: Verdadero. La lógica booleana se basa en el comportamiento de los
circuitos lógicos y es un pilar fundamental para la programación en hardware y software.
7. Verdadero/Falso: Verdadero. El operador booleano de negación not (!) es un operador
unitario que acepta una única entrada booleana y devuelve el valor opuesto.
8. Verdadero/Falso: Verdadero. Una de las desventajas de la modularización es que puede
ser más complicado encontrar errores en el código, ya que el código se divide en diferentes
módulos.
9. Verdadero/Falso: Verdadero. El operador booleano or (||) produce verdadero si cualquiera
de las dos entradas es verdadero.
10. Verdadero/Falso: Falso. El operador booleano and (&&) es un operador booleano que
acepta dos entradas booleanas y produce una sola salida booleana. Solo producirá el valor
verdadero si ambas entradas son verdaderas.
1 - ¿Por qué los objetos?
En la programación, es fundamental el uso de variables para almacenar distintos tipos de
datos, como enteros, texto y booleanos. Sin embargo, cuando se trata de una cantidad
variada de datos, surge la necesidad de tenerlos agrupados bajo una única variable de tipo
de datos complejo. Estos tipos de datos se llaman objetos o registros, y contienen datos y
funciones, a las que se les llama métodos del objeto.
Aunque la notación de objetos es muy parecida en todos los lenguajes de programación, en
este caso se presentarán ejemplos en JavaScript. Los objetos son importantes porque
permiten agrupar y organizar datos relacionados en una única variable, lo que hace que sea
más fácil y eficiente trabajar con ellos. Por ejemplo, si se tiene un programa para un taller
mecánico, donde se deben almacenar los datos de cada auto en reparación, se necesita
saber la marca, modelo, color, año, cantidad de puertas, tamaño del motor y kilometraje de
cada auto.
Si se trabajara con variables para cada propiedad de un objeto, se tendría que definir una
variable por cada propiedad, lo que se vuelve poco práctico y poco eficiente en el uso de
variables. Por ejemplo, para un auto, se tendría que definir las variables marca, modelo,
color, año, cantidad de puertas, tamaño del motor y kilometraje. Si se trabajara con un
objeto que tenga 50 propiedades, se tendría que definir 50 variables, lo que sería poco
práctico.
Es aquí donde definir un objeto ataca este problema, agrupando todas las características
que conforman un único objeto, en este caso un auto. Por ejemplo, se puede definir un
objeto auto que contenga todas las propiedades mencionadas anteriormente, y acceder a
ellas a través de la notación de punto. Esto hace que el código sea más limpio, organizado y
eficiente.
Por ejemplo, para definir un objeto auto en JavaScript, se puede hacer lo siguiente:
```
let auto = {
marca: "Fiat",
modelo: "Uno",
color: "Rojo",
año: 2003,
cantPuertas: 5,
tamMotor: 1.5,
kilometraje: 80000
};
```
En este caso, se define un objeto auto que contiene las propiedades marca, modelo, color,
año, cantidad de puertas, tamaño del motor y kilometraje. Cada propiedad se define con un
nombre y un valor separados por dos puntos. Para acceder a una propiedad de un objeto,
se utiliza la notación de punto, por ejemplo:
```
let marcaAuto = [Link];
```
Esto asignará el valor "Fiat" a la variable marcaAuto, ya que se está accediendo a la
propiedad marca del objeto auto.
En resumen, los objetos son una herramienta fundamental en la programación orientada a
objetos y nos permiten escribir código más limpio, organizado y eficiente. Al agrupar y
organizar datos relacionados en una única variable, podemos acceder a ellos de manera
más fácil y eficiente, lo que hace que nuestro código sea más modular y fácil de mantener.
2 - Creando objetos
Los objetos en programación permiten agrupar valores de propiedades y acceder a ellos a
través de una única variable. Por ejemplo, un objeto auto se puede crear de la siguiente
manera en JavaScript:
```javascript
let auto = {
marca: "Fiat",
modelo: "Uno",
color: "Rojo",
año: 2003,
cantPuertas: 5,
tamMotor: 1.5,
kilometraje: 80000
};
```
Algunas características importantes al definir un objeto son:
1. Por claridad, se define una propiedad y un valor por línea.
2. En cada línea, se define el nombre de la propiedad y un valor, separados por dos puntos (
: ).
3. Las propiedades se separan entre sí por una coma ( , ).
4. El conjunto de propiedades se encuentra entre llaves ( {} ).
Trabajando con las propiedades
Las propiedades de un objeto son básicamente lo mismo que las variables comunes,
excepto por el nexo con el objeto. Las propiedades de un objeto definen las características
del mismo. Podemos acceder a las propiedades de un objeto con una simple notación de
punto:
```javascript
[Link]
```
Es decir que para acceder a la propiedad de la marca del auto:
```javascript
[Link]
```
Tener en cuenta que las propiedades no asignadas de un objeto son undefined, es decir que
si ejecutamos `[Link]`, el resultado será undefined, ya que la propiedad ancho no se
encuentra definida.
También se puede acceder o establecer propiedades de objetos mediante la notación de
corchetes [ ]. Así, por ejemplo, se puede acceder a las propiedades del objeto auto de la
siguiente manera:
```javascript
auto["marca"] = "Fiat";
auto["modelo"] = "Uno";
auto["año"] = 2003;
```
Nota: es recomendable no utilizar esta forma, ya que es más intuitivo y sencillo hacerlo a
partir del punto.
Tener en cuenta también que hasta ahora hemos trabajado con tipos de datos simples como
propiedades, pero podríamos agregar un nivel de complejidad, de forma tal que una cierta
propiedad de un objeto, sea otro objeto.
Supongamos que queremos especificar las dimensiones del auto, podríamos crear 3
propiedades: ancho, alto, largo. Pero tal vez podríamos crear otro objeto, llamémosle
dimension, que este tenga las 3 propiedades de dimensiones recién mencionadas:
```javascript
let dimension = {
ancho: 140,
alto: 160,
largo: 250
};
```
Ahora resta que el objeto auto tenga una nueva propiedad y asignarle el objeto recién
creado:
```javascript
[Link] = dimension;
```
Recordemos que para acceder a la propiedad de un objeto, tenemos 2 formas:
```javascript
[Link]
// o
auto["medidas"]
```
Hasta aquí estaremos accediendo al objeto que almacenamos en la propiedad medidas.
Para acceder a las propiedades del objeto de dimensión (objeto con las 3 propiedades de
alto, ancho y largo), debemos hacerlo como lo hacemos con cualquier objeto, por ejemplo
para acceder a la medida del largo del auto:
```javascript
[Link];
// o
auto["medidas"]["alto"];
```
Es decir que cuando escribimos `[Link]`, accedemos al objeto de tipo dimensiones
(que se encuentra bajo la propiedad medidas del objeto auto), y luego con `.alto` estaremos
accediendo a la propiedad alto del objeto dimensiones. De forma análoga con
`auto["medidas"]`, para luego acceder a la propiedad alto escribiendo `["alto"]`. De esta
forma `[Link]` vale 160.
3 - Arreglos
En la sección anterior, aprendimos sobre objetos como una forma de agrupar información
relacionada bajo una única variable, accediendo a sus propiedades mediante etiquetas o
nombres. Ahora, exploraremos otra forma de agrupación llamada arreglo (o array en inglés),
que se accede a través del orden en que los elementos fueron insertados.
Un arreglo se crea utilizando corchetes ([]), y se pueden ingresar elementos dentro de él.
Por ejemplo:
```javascript
let bebidas = ["Café", "Té", "Chocolate"];
```
Para acceder a los elementos del arreglo, utilizamos corchetes y el índice del elemento,
comenzando desde 0:
```javascript
let primerBebida = bebidas[0]; //"Café"
let segundaBebida = bebidas[1]; //"Té"
let tercerBebida = bebidas[2]; //"Chocolate"
```
También podemos crear un arreglo vacío e insertar elementos uno por uno usando la
función `push()`:
```javascript
let bebidas = []; // arreglo inicialmente vacío
[Link]("Café"); //bebidas = ["Café"]
[Link]("Té"); //bebidas = ["Café", "Té"]
[Link]("Chocolate"); //bebidas = ["Café", "Té", "Chocolate"]
```
Para eliminar el último elemento del arreglo, usamos la función `pop()`:
```javascript
let bebidaEliminada = [Link](); //retornará "Chocolate"
```
Si queremos eliminar un elemento que no está al final del arreglo, primero encontramos su
posición con `indexOf()` y luego lo eliminamos con `splice()`:
```javascript
let posCafe = [Link]("Café"); //retornará 0
let bebidaEliminada = [Link](posCafe, 1);
//retornará el elemento eliminado "Café" y lo quitará del arreglo bebidas
```
Para conocer la cantidad de elementos en el arreglo, utilizamos la propiedad `length`:
```javascript
let cantElementos = [Link]; //retornará 3
```
Resumen de operaciones con arreglos:
| Operación | Descripción |
|------------------------------------|---------------------------------------------------------------|
| let arr = []; | Define un arreglo sin elementos. |
| let arr = [elem1, elem2]; | Define un arreglo y lo inicializa con valores. |
| [Link](elem); | Inserta el elemento elem en el arr. |
| let eliminado = [Link](); | Quita el último elemento del arreglo arr y lo retorna. |
| let posElem = [Link](elem); | Devuelve la posición donde se encuentra el elemento
elem en el arreglo arr. |
| let eliminado = [Link](posElem, 1); | Elimina el elemento en la posición posElem del
arreglo arr. |
| let cantElementos = [Link]; | Devuelve la cantidad de elementos del arreglo arr.
|
4 - Arreglos con objetos
En esta sección, hemos visto las operaciones básicas para manejar arreglos, aunque
solamente lo vimos con elementos de tipo texto, simplemente por mantener los ejemplos
simples. En realidad, los arreglos permiten trabajar con cualquier tipo de datos, incluso con
objetos, como los que venimos viendo. Incluso, un único arreglo puede contener elementos
de distintos tipos de datos.
Por ejemplo, podemos tener un arreglo que contenga elementos de tipo texto, entero y
booleano respectivamente:
```
let elemVarios = ["Café", 100, false];
```
En este caso, tenemos 3 elementos contenidos en el arreglo `elemVarios`, pero a diferencia
de los ejemplos anteriores donde todos los elementos eran de tipo texto, en este caso
tenemos los tipos de datos: texto, entero y booleano respectivamente.
Incluso podemos ir más allá e incluir elementos de tipo objetos que hemos definido:
```
let bebida = {
nombre : "Café",
ingredientes : "Grano de café",
alcoholica: false
};
[Link](bebida);
//elemVarios = ["Café", 100, false, bebida]
```
Se sigue cumpliendo que para acceder a un elemento del arreglo, debemos especificar la
posición. En este caso, el objeto insertado `bebida` se encuentra en la posición 3 (recordar
que las posiciones comienzan a partir de 0, por lo tanto la posición 3 corresponde al 4to.
elemento en el arreglo).
```
let nombreBebida = elemVarios[3].nombre;
```
Esto retornará "Café", ya que con `elemVarios[3]` accedemos al objeto `bebida`, y como ya
vimos, para acceder a la propiedad de un objeto, lo hacemos a través del `.` y su nombre,
en este caso `.nombre`.
Iterando entre objetos
Una vez que ya sabemos:
- Crear objetos y acceder a las propiedades.
- Los arreglos y sus operaciones básicas.
- Los objetos contenidos en un arreglo.
Estamos en condiciones de ver cómo podemos navegar entre ellos: es decir, ir accediendo
entre un objeto y otro contenidos en una agrupación o colección (en este caso un arreglo).
Esto es muy utilizado en la programación, ya que es muy frecuente la situación en la que
debemos iterar (otra forma de decir la navegación) entre objetos para recopilar información.
Por ejemplo, retomando el ejemplo del taller mecánico, donde contamos con un inventario
de los autos en reparación: supongamos que el inventario se trata de un arreglo
conteniendo muchos elementos de tipo auto, y el coordinador del taller desea saber todos
los autos que se encuentra en reparación, y con más de 1000 kilómetros.
Recordar que la cantidad de kilómetros que tiene un auto la sabemos a partir de la
propiedad `.kilometraje`, entonces, ¿cómo podemos hacer esto? Para esto debemos
introducir la estructura de iteración `for`.
El `for` es una estructura de repetición, un poco distinta al `while` y al `repeat` (como se vio
en Gobstones). La diferencia es que en una sola línea, indicamos:
```
1. La instrucción inicial bajo la que se ejecutará una única vez, al comienzo de la repetición.
2. La condición de continuidad que se estará evaluando en cada repetición, que en caso
que sea verdadera, se ejecutará el bloque de código dentro del for, de lo contrario finalizará
la repetición.
3. La instrucción que se ejecutará entre cada repetición.
```
Tendrá la siguiente estructura:
```
for (ins. inicial; cond. continuidad; ins. repetición) {
//código a ejecutar en cada repetición
}
```
Por ejemplo, si quisiéramos insertar los primeros 100 números en un arreglo:
```
let numeros = [];
//inicializamos un arreglo vacío
for (let i = 1; i <= 100; i++) {
[Link](i);
}
```
Nota: `i++` en la mayoría de los lenguajes se utiliza por un tema de simpleza, es equivalente
a `i = i + 1`, es decir que incrementa en una unidad a la variable.
En este ejemplo:
1. Instrucción inicial: `let i = 1`. Es decir que creamos la variable `i`, y le asignamos el valor
1.
2. Condición de continuidad: `i <= 100`. Es decir que la repetición se estará ejecutando
mientras `i` sea menor o igual a 100.
3. Recordar que comenzará en 1, debido a la Instrucción inicial.
4. Instrucción entre cada repetición: `i++`. Es decir que cada vez que finalice la ejecución de
una repetición, se ejecutará ésta.
5. Instrucción, que en este caso incrementa a `i` en una unidad.
6. El bloque de código del `for`: `[Link](i)`, esta instrucción inserta en el arreglo
`numeros`, el valor de `i`. Debido a que `i` comenzará en 1 y finalizará en 100, se habrán
insertado en dicho arreglo, los primeros 100 números.
Retomando el ejemplo del taller mecánico, si queremos averiguar cuántos son los autos que
se encuentran en el taller, cuyo kilometraje sea igual o mayor a 1000 kilómetros, una forma
podría ser la siguiente:
```
let cantAutos = 0;
for (let i = 0; i < [Link]; i++) {
if (arrAutos[i].kilometraje >= 1000) {
cantAutos++;
}
}
```
Detallemos:
- `let cantAutos = 0;`: Aquí inicializamos en 0 la variable numérica, que irá representando la
cantidad de autos que encontramos según el criterio solicitado: “cuyo kilometraje sea igual o
superior a 1000 kilómetros”.
- `for (let i = 0; i < [Link]; i++)`: haremos uso de la variable numérica `i`, para ir
navegando entre los elementos del arreglo, es decir que dicha variable será la posición a la
que estaremos accediendo del arreglo. Como estará siendo la posición del arreglo, no se
deberá de ir más allá de los límites del arreglo, por eso debe ser menor que el largo.
Recordar que la posición comienza en 0, entonces si el arreglo tuviera 10 elementos, la
posición debería ir desde 0 hasta 9, es por esto que se utiliza el `<` y no el `<=`.
- `if (arrAutos[i].kilometraje >= 1000)`: recordemos que al acceder al arreglo a partir de la
posición, estaremos accediendo al objeto y sus propiedades. Es por esto que con
`arrAutos[i]` accederemos al objeto que se encuentra en la posición `i`, y conociendo las
propiedades del objeto auto (en este caso a `kilometraje`), estaremos accediendo a ella a
partir del `.kilometraje`. Finalmente, consultamos si es mayor o igual a 1000, para saber si
tomar en cuenta el auto, que en caso que lo sea, incrementamos en una unidad la variable
que lo cuenta (`cantAutos`).