Autor Tema: JavaScript costes computacionales complejidad Habilitar campos select CU01183E#  (Leído 4040 veces)

bermartinv

  • Avanzado
  • ****
  • APR2.COM
  • Mensajes: 298
    • Ver Perfil
Hola chicos!!,

Adjunto mi solución para este tema CU01183E del tutorial de programador web JavaScript desde cero y planteo un problema que me ha surgido.

A la hora de resolver problemas tengo claro que cuanto mas condiciones haya más tiempo tarda en ejecutarse el código. Pero por ejemplo es mucha la diferencia entre por ejemplo:

- Un for o varios if,else if enlazados.
-Un switch o varios if,else if enlazados.

Citar
a) Deberá presentarse un formulario con 2 elementos select. El primer elemento select permitirá elegir país y podrá elegirse entre México, España, Perú y Colombia.

b) El segundo elemento select permitirá elegir ciudad y podrá elegirse entre México D.F., Guadalajara, Madrid, Barcelona, Lima, Trujillo, Bogotá y Cali.

c) Si el usuario selecciona ciudad sin haber elegido país, deberá mostrarse como opción elegida de país el país correspondiente a la ciudad. Por ejemplo, si el usuario selecciona Bogotá deberá aparecer como país seleccionado Colombia.

d) Si el usuario selecciona un país en primer lugar, deberán deshabilitarse todas las opciones que no correspondan a ciudades de ese país. Por ejemplo si el usuario elige España, sólo podrá elegir entre Madrid y Barcelona, debiendo estar México D.F., Guadalajara, Lima, Trujillo, Bogotá y Cali deshabilitadas. Si el usuario cambia el país, deberán cambiar las ciudades cuya elección es posible.

e) Ampliación opcional para el ejercicio: introduce medidas de seguridad adicionales para que no puedan existir incoherencias entre el país seleccionado y la ciudad. Por ejemplo, imagina que el usuario elige en primer lugar como ciudad México D.F. y luego elige como país Perú. Introduce medidas de seguridad que impidan que esto suceda.

Código: [Seleccionar]
<!DOCTYPE html>

<html><head><title>Ejemplo aprenderaprogramar.com</title><meta charset="utf-8">

<style type="text/css"> body, p {margin-left:30px; font-family: sans-serif;}

.estiloForm {background-color: #f3f3f3; border: solid 2px black; margin-left:20px; width: 330px; padding:10px; }

.estiloForm label {display: block; width: 120px; float: left; text-align:right; margin-bottom: 35px; padding-right: 20px;}

br {clear: left;} input[type="submit"], input[type="reset"] {margin:25px 5px 10px 5px;}

</style>

<script type="text/javascript">

window.onload = function () {

 var select1 = document.formularioContacto.pais;
   
 var select2 = document.formularioContacto.ciudad;
   
    select1.addEventListener('change',function(){primerSelect(this,select2)});
   
    select2.addEventListener('change',function(){segundoSelect(select1,this)});   
   
}   

function primerSelect(select1,select2){
    for (var i=1;i<select1.length;i++){
     if (select1.options[i].selected ){habilitarCiudad(i,select2)}
    }
}
   
   
function habilitarCiudad(opcion,select2){
    switch (opcion){
        case 1 :habilitar(select2);
                select2.options[1].disabled = false;
                select2.options[2].disabled = false;
            break;
        case 2 :habilitar(select2);
                select2.options[3].disabled = false;
                select2.options[4].disabled = false;
            break;
        case 3 :habilitar(select2);
                select2.options[5].disabled = false;
                select2.options[6].disabled = false;
            break;
        case 4 :habilitar(select2);
                select2.options[7].disabled = false;
                select2.options[8].disabled = false;
            break;
       
    }
       
}
   
function segundoSelect(select1,select2){
    for (var i=1;i<select2.length;i++){
    if (select2.options[i].selected ){habilitarPais(i,select1)}
    }
}
 

function habilitarPais(opcion,select1){
    switch (opcion){
        case 1 :
        case 2 :
                habilitar(select1);
                select1.options[1].disabled = false;
                select1.value = 'mejico';
                break;
        case 3 :
        case 4 :
                habilitar(select1);
                select1.options[2].disabled = false;
                select1.value = 'españa';
                break;
        case 5 :
        case 6 :
                habilitar(select1);
                select1.options[3].disabled = false;
                select1.value = 'peru';
                break;
        case 7 :
        case 8 :
                habilitar(select1);
                select1.options[4].disabled = false;
                select1.value = 'colombia';
                break;
       
    }
       
}

   
function habilitar(select){
    for (var i = 0; i < select.length; i++){
            select.options[i].disabled = true;
        }

}

</script>

</head>

<body><h2>Cursos aprenderaprogramar.com</h2><h3>Ejemplos JavaScript</h3>

                <div class="estiloForm">

                              <form name ="formularioContacto" method="get" action="http://aprenderaprogramar.com">

                               <label>País de turismo</label><select id="pais" name="pais">

                               <option value="">Elija país</option>

                               <option value="mejico">México</option>

                               <option value="españa">España</option>

                               <option value="peru">Perú</option>
                               
                               <option value="colombia">Colombia</option>

                               </select><br/>
                               
                               <label>Ciudad de turismo</label><select id="ciudad" name="ciudad">

                               <option value="">Elija una ciudad</option>

                               <option value="mejicodf">México D.F.</option>

                               <option value="guadalajara">Guadalajara</option>

                               <option value="madird">Madrid</option>
                               
                               <option value="barcelona">Barcelona</option>
                               
                               <option value="lima">Lima</option>
                               
                               <option value="trujillo">Trujillo</option>
                               
                               <option value="bogota">Bogotá</option>
                               
                               <option value="cali">Cali</option>

                               </select><br/>

                               <input class="botonFormulario" type="submit" value="Enviar"/>

                               <input class="botonFormulario" type="reset" value="Cancelar"/>

                </form>

                </div>
</body></html>

Saludos!!!!
« Última modificación: 14 de Enero 2022, 19:08 por Ogramar »

pedro,,

  • Moderador Global
  • Experto
  • *******
  • APR2.COM
  • Mensajes: 1292
    • Ver Perfil
Re:Habiltar campos de un select. CU01183E
« Respuesta #1 en: 29 de Marzo 2016, 23:28 »
Hola bermartinv.

Si selecciono por ejemplo 'México' y sin tocar nada en el select de ciudades, luego cambio el país por 'elija país', en el select de ciudades solo deja seleccionar las ciudades que pertenecen a 'México' aunque en el select de países ya no este seleccionado.

Si selecciono 'México' y en el select de ciudades selecciono una de las ciudades que pertenecen a 'México', después ya no hay forma de seleccionar ninguna otra cosa, ni siquiera 'elija país' ni 'elija ciudad' a no ser que se actualice la página.

Así que toca rectificar.

Saludos. ;D
« Última modificación: 29 de Marzo 2016, 23:29 por pedro,, »

bermartinv

  • Avanzado
  • ****
  • APR2.COM
  • Mensajes: 298
    • Ver Perfil
Re:JavaScript. Habiltar campos de un select. CU01183E
« Respuesta #2 en: 30 de Marzo 2016, 18:08 »
Gracias pedro,,
por corregirme, la verdad que este es uno de los ejercicios que más me ha costado y no por su dificultad. Al comenzar a realizar el ejercicio no me puse un esquema de ataque  ;D, y he ido realizando el código a salto de mata.

Adjunto código rectificado.

Código: [Seleccionar]
<!DOCTYPE html>

<html><head><title>Ejemplo aprenderaprogramar.com</title><meta charset="utf-8">

<style type="text/css"> body, p {margin-left:30px; font-family: sans-serif;}

.estiloForm {background-color: #f3f3f3; border: solid 2px black; margin-left:20px; width: 330px; padding:10px; }

.estiloForm label {display: block; width: 120px; float: left; text-align:right; margin-bottom: 35px; padding-right: 20px;}

br {clear: left;} input[type="submit"], input[type="reset"] {margin:25px 5px 10px 5px;}

</style>

<script type="text/javascript">

window.onload = function () {

 var select1 = document.formularioContacto.pais;
   
 var select2 = document.formularioContacto.ciudad;
   
    select1.addEventListener('change',function(){primerSelect(this,select2)});
   
    select2.addEventListener('change',function(){segundoSelect(select1,this)});   
   
}   

function primerSelect(select1,select2){
    for (var i=0;i<select1.length;i++){
     if (select1.options[i].selected ){habilitarCiudad(i,select2,select1)}
    }
}
   
   
function habilitarCiudad(opcion,select2,select1){
    switch (opcion){
           
        case 0 :select2.value = '';
                habilitar(select1,false);
                habilitar(select2,false);
            break;
        case 1 :habilitar(select2,true);
                select2.options[1].disabled = false;
                select2.options[2].disabled = false;
            break;
        case 2 :habilitar(select2,true);
                select2.options[3].disabled = false;
                select2.options[4].disabled = false;
            break;
        case 3 :habilitar(select2,true);
                select2.options[5].disabled = false;
                select2.options[6].disabled = false;
            break;
        case 4 :habilitar(select2,true);
                select2.options[7].disabled = false;
                select2.options[8].disabled = false;
            break;
       
    }
       
}
   
function segundoSelect(select1,select2){
    for (var i=0;i<select2.length;i++){
    if (select2.options[i].selected ){habilitarPais(i,select1,select2)}
    }
}
 

function habilitarPais(opcion,select1,select2){
    switch (opcion){
        case 0 :select1.value = '';
                habilitar(select1,false);
                habilitar(select2,false);
            break;
        case 1 :
        case 2 :
                habilitar(select1,true);
                select1.options[1].disabled = false;
                select1.value = 'mejico';
            break;
        case 3 :
        case 4 :
                habilitar(select1,true);
                select1.options[2].disabled = false;
                select1.value = 'españa';
            break;
        case 5 :
        case 6 :
                habilitar(select1,true);
                select1.options[3].disabled = false;
                select1.value = 'peru';
            break;
        case 7 :
        case 8 :
                habilitar(select1,true);
                select1.options[4].disabled = false;
                select1.value = 'colombia';
            break;
       
    }
       
}

   
function habilitar(select,boolean){
    for (var i = 1; i < select.length; i++){
            select.options[i].disabled = boolean;
        }

}

</script>

</head>

<body><h2>Cursos aprenderaprogramar.com</h2><h3>Ejemplos JavaScript</h3>

                <div class="estiloForm">

                              <form name ="formularioContacto" method="get" action="http://aprenderaprogramar.com">

                               <label>País de turismo</label><select id="pais" name="pais">

                               <option value="">Elija país</option>
                               <option value="mejico">México</option>
                               <option value="españa">España</option>
                               <option value="peru">Perú</option>
                               <option value="colombia">Colombia</option>
                               </select><br/>
                               
                               <label>Ciudad de turismo</label><select id="ciudad" name="ciudad">

                               <option value="">Elija una ciudad</option>
                               <option value="mejicodf">México D.F.</option>
                               <option value="guadalajara">Guadalajara</option>
                               <option value="madird">Madrid</option>
                               <option value="barcelona">Barcelona</option>     
                               <option value="lima">Lima</option>
                               <option value="trujillo">Trujillo</option>
                               <option value="bogota">Bogotá</option>
                               <option value="cali">Cali</option>
                               </select><br/>

                               <input class="botonFormulario" type="submit" value="Enviar"/>
                               <input class="botonFormulario" type="reset" value="Cancelar"/>

                </form>

                </div>
</body></html>

Por cierto, ¿qué opinas de lo que puse en el primer mensaje de este hilo, sobre las condicionales y sobre el tiempo de ejecución?. Es que aparte de la visualización de código supongo que será más correcto utilizar sentencias for o switch que if o else if, no?

Saludos!!!!
« Última modificación: 14 de Enero 2022, 19:05 por Ogramar »

Alex Rodríguez

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2050
    • Ver Perfil
Re:JavaScript. Habiltar campos de un select. CU01183E
« Respuesta #3 en: 30 de Marzo 2016, 22:53 »
Hola, voy a comentar algo sobre la cuestión planteada por bermartinv. El tiempo que tarda en ejecutarse un código depende de varias cosas, entre ellas el diseño del código y la máquina sobre la que se ejecuta, el estado de la máquina, etc.

Para poder hacer comparaciones homogéneas normalmente el estudio se hace a nivel teórico y se suele hablar de órdenes de complejidad ó cotas superiores de coste.

El coste se suele estudiar en dos aspectos: espacio, normalmente referido al consumo de memoria que se realiza, y tiempo, normalmente referido al número de operaciones que se realizan (esto es así para poder hacer comparaciones homogéneas).

Es un tema interesante pero complejo, voy a dar algunas pistas, quien quiera investigar podrá encontrar mucha información en internet buscando "complejidad computacional".

Supongamos los siguientes códigos en un lenguaje imaginario

Código A

for i=1 to 15 {
mostrar "hola"
}


Código B

if i=1 { mostrar "hola1"}
elseif i=2 { mostrar "hola" }
elseif i=3 {mostrar "hola3" }
elseif i=4 {mostrar "hola4" }
elseif i=5 {mostrar "hola5" }

Simplificadamente se sigue esta regla: el coste de una operación es 1. En el código A tenemos una operación: mostrar "hola", cuyo coste es 1, pero como el código se repite 15 veces el coste es 15.

En el código B tenemos que quizás se cumpla la primera condición y entonces ya no se evalúan las demás, el coste sería 1. Pero si no se cumple la primera sino la segunda el coste sería 2. Pero si no se cumple la primera ni la segunda... Bueno, no se sabe lo que va a ocurrir. Entonces lo que hacemos es tomar la cota superior, es decir, el coste más grande que pudiéramos tener. El coste más grande sería tener que evaluar los cinco condicionales, con lo que el coste sería 5. En realidad podríamos decir que evaluar los 5 condicionales más el coste de la instrucción mostrar nos lleva a 6, pero en esos detalles no se suele entrar.

Muchas veces se puede diseñar un código de varias maneras, y muchas veces esto no implica variaciones significativas en el coste. Por ejemplo ejecutar un bucle con 5 repeticiones o tener 5 if viene teniendo un coste similar.

Otras veces sí tiene importancia el diseño. Algo con lo que se debe tener cuidado son los bucleas anidados, por ejemplo

for i=1 to 10
   for j = 1 to 10
      mostrar "hola"
   next j
next i

¿Qué ocurre aquí? Por cada repetición del bucle i hay 10 repeticiones del bucle j. Esto nos lleva a un coste de 10x10 = 100. Con bucles anidados los costes se disparan rápidamente.

Todo esto puede extenderse mucho, pero espero al menos que sirva como idea.

Saludos

bermartinv

  • Avanzado
  • ****
  • APR2.COM
  • Mensajes: 298
    • Ver Perfil
Gracias Alex Rodríguez,
muy aclaratoria tu explicación.

pedro,,

  • Moderador Global
  • Experto
  • *******
  • APR2.COM
  • Mensajes: 1292
    • Ver Perfil
Buenas.

El código ahora va bien.

En cuanto a lo segundo, pues como dice Alex, no es algo fácil. Pero puedes encontrar mucha información por la red.

En cuanto al caso que comentas sobre un switch o varios if,else if enlazados en algunos sitios leí que el switch es más rápido por aquello de no tener que hacer la comprobación en cada caso, pero de manera demostrada, quiero decir con tiempos de ejecución y demás no me encontré nada.
Lo que sí vi en bastantes sitios es que es mas rápido usar un objeto y referirnos a sus propiedades en vez de usar switch o if enlazados.
Te pongo un ejemplo y así no te lío mas, el ejemplo está realizado sobre el ejercicio que se plantea en la entrega CU01120E.

Código: [Seleccionar]
<html>
<head>
<title>Curso JavaScript aprenderaprogramar.com. CU01120E</title> <meta charset="utf-8">
<script type="text/javascript">
function usandoObjeto() {
var tipoMotor = Number(prompt('Introduzca el tipo de motor de una bomba para mover fluidos (del 1 al 4)'));
var motor = {
1: 'agua',
2: 'gasolina',
3: 'hormigón',
4: 'alimentación'
}
if(motor[tipoMotor]){
alert('La bomba es una bomba de ' + motor[tipoMotor]);
} else {
alert('No hay establecido un valor definido para el tipo de bomba.');
}
}
function usandoSwitch() {
var tipoMotor;
tipoMotor = prompt('Introduzca el tipo de motor de una bomba para mover fluidos (del 1 al 4)');
tipoMotor = Number(tipoMotor);
switch(tipoMotor){
case 0:
alert('No hay establecido un valor definido para el tipo de bomba.');
break;
case 1:
alert('La bomba es una bomba de agua.');
break;
case 2:
alert('La bomba es una bomba de gasolina.');
break;
case 3:
alert('La bomba es una bomba de hormigón.');
break;
case 4:
alert('La bomba es una bomba de pasta alimenticia.');
break;
default:
alert('No existe un tipo de bomba válido para tipo de motor ' + tipoMotor + '.')
break;
}
}
</script>
</head>
<body>
<div>
<p>Desarrolla un script donde trabajas con tipos de motor(suponemos que se trata del motor de una bomba para mover fluidos)</p>
<p>Pinche sobre la imagen para comenzar...</p>
<button onclick="usandoObjeto()">Tipo de motor usando objetos</button>
<button onclick="usandoSwitch()">Tipo de motor usando switch</button>
</div>
</body>
</html>

Saludos.  ;D

bermartinv

  • Avanzado
  • ****
  • APR2.COM
  • Mensajes: 298
    • Ver Perfil
si pedro,, en ese sentido tienes batante razón. Por lo que estoy viendo la potencia de javascript es su funcionalidad de objetos y referencias, y sería conveniente crear todo como objetos y trabajar con sus metodos y sus propiedades. ::)

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".