/ Published in: JavaScript
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
<!-- Inserto el doctype para que sea XHTML 1.0 transicional --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <!-- Inicio la cabecera de mi documento HTML --> <head> <!-- Pongo el titulo de la pagina --> <title>Ejercicio</title> <!-- Mando llamar el framework de jquery desde google con el google API --> <script src="http://www.google.com/jsapi"></script> <script> google.load("jquery", "1.5.0"); </script> <!-- Defino un par de estilos para poder mandarle alertas o error al usuario --> <style type="text/css"> /* Defino una clase de alerta que me da un color de fondo amarillo claro */ .warning { background-color: #FAFAD2; } /* Defino una clase de error que me da un color de fondo rojo claro */ .error { background-color: #FFF0F5; } </style> </head> <!-- Inicio el cuerpo de mi documento HTML --> <body> <!-- Escribo las instrucciones para el usuario en un parrafo --> <h2>Ejercicio</h2> <h3>Introducción</h3> <p>La forma de abajo captura los datos requeridos para el ejercicio.</p> <p> Comente todos los console.log() para que no haya problema en cargar el javascript. (Aún con la function stub de la linea 370, a veces no ejecuta el javascript si no se tiene abierto el firebug en firefox.) </p> <br /> <p> Introduzca dos números enteros, el Número B tiene que ser mayor al A </p> <!-- Creo una forma sin ninguna acción, porque lo capturara javascript --> <form id="ejercicio"> <!-- Creo una etiqueta asociada a mi input para obtener el dato del primer numero --> <label for="numeroA">Número A</label> <!-- Creo un input que recibira el primer numero --> <input type="text" name="numeroA" id="numeroA"/> <!-- Creo un campo que mostrara errores o advertencias para mi primer numero --> <span id="msgA"></span> <!-- Utilizo un salto de linea para mostrar el siguiente input debajo --> <br /> <!-- Creo una etiqueta asociada a mi input para obtener el dato del segundo numero --> <label for="numeroB">Número B</label> <!-- Creo un input que recibira el segundo numero --> <input type="text" name="numeroB" id="numeroB"/> <!-- Creo un campo que mostrara errores o advertencias para mi segundo numero --> <span id="msgB"></span> <!-- Utilizo un salto de linea para mostrar el boton-input debajo --> <br /> <!-- Uso un boton para que el usuario le de click --> <input class="submit" type="submit" value="Enviar" id="submit"/> <span id="msgSubmit"></span> <!-- Inserto un salto de linea entre mi resultado y los mensajes de error --> <br /> <!-- Elemento donde voy a ir mostrando el resultado --> <span>Resultado:</span><br /> <ul id="result"> </ul> </form> <!-- Usaré javascript para resolver el ejercicio, uso el framework de jQuery para simplificar cosas. --> <script type="text/javascript" > /** * Ejercicio * * @Author: Héctor De Diego Brito * @Date: 22 de febrero del 2011 * @Version: v0.1 */ // Creo un array global donde vaya metiendo mis numeros la funcion // getRandom. Lo vacio cada vez que le da click para que no haya un // leak de memoria cuando vuelvo a llamar el metodo getRandom() var randomArray = []; // Creo mis indices var i = 0; var j = 0; var k = 0; /** * Defino una funcion que obtiene los datos de los campos y los convierte * en enteros. */ function getData() { //console.log("Obteniendo la informacion de la forma"); // Obtengo en la variable local valA el valor introducido en el campo // con id "numeroA" var valA = $("#numeroA").val(); // Convierto a entero el dato obtenido valA = parseInt(valA); // Reviso si introdujeron letras o caracteres invalidos con la funcion // isNan if (isNaN(valA)) { // Mando un mensaje de error al span que cree de mensajes, concateno // funciones para primero cambiar el HTML y luego cambiar el CSS al // meterle una clase de CSS $("#msgA").html("El campo debe ser un numero") .addClass('warning'); } else { // Si no es NaN me debe desaparecer el mensaje y quitar la clase de // CSS que me cambia el color de fondo $("#msgA").html("") .removeClass('warning'); } // Obtenigo en la variable local valB el valor introducido en el campo // con id "numeroB" var valB = $("#numeroB").val(); // Convierto a entero el dato obtenido valB = parseInt(valB); // Reviso si introdujeron letras o caracteres invalidos con la funcion // isNan if (isNaN(valB)) { // Mando un mensaje de error al span que cree de mensajes, concateno // funciones para primero cambiar el HTML y luego cambiar el CSS al // meterle una clase de CSS $("#msgB").html("El campo debe ser un numero") .addClass('warning'); } else { // Si no es NaN me debe desaparecer el mensaje y quitar la clase de // CSS que me cambia el color de fondo $("#msgB").html("") .removeClass('warning'); } // Imprimo en consola el valor del dato A //console.log("El valor de A: " + valA); // Imprimo en consola el valor del dato B //console.log("El valor de B: " + valB); // Los if's anteriores solo me mandan los mensajes de alerta, en este // if valido que ambos datos sean numeros con logica negativa, ya que // la funciona isNan me regresa que es verdadero si es NAN, y quiero // verificar que no sean NaN (es decir, vacios, letras o simbolos) if (!isNaN(valA) && !isNaN(valB)) { // Reviso que el primer numero sea menor al mayor y que no sean // iguales if ((valB > valA) && (valB != valA)) { // Envio un mensaje a consola confirmando si ambos numeros son // int's //console.log("Ambos numeros son enteros"); // Inicializo un arreglo local de dos espacios var resultSet = [2]; // En la primera posicion de mi arreglo meto el valor A resultSet[0] = valA; // En la segunda posicion de mi arreglo meto el valor B resultSet[1] = valB; // Imprimo el contenido de mi arreglo en consola //console.log("El contenido de resultSet es " + resultSet); // Mando un mensaje de exito al usuario. $("#msgSubmit").html("Datos capturados") .removeClass('error'); // Regreso en un arreglo mis dos datos return resultSet; } else { $("#msgSubmit").html("El numero B tiene que ser mayor al numero A") .addClass('error'); return false; } // En caso de que no sean numeros, mando un mensaje de error y no guardo // los datos en el arreglo. } else { // Si ambos numeros son NaN, a un lado del input me debe salir un // Mensaje de error. $("#msgSubmit").html("Error. Introduzca numeros enteros") .addClass('error'); return false; } } // Reviso si el numero es impar function isOddNumber(someNumber) { //console.log("Revisando si el numero es impar"); // Uso la forma corta/shorthand para hacer un if y la asigno directamente // al return: usando el operador Modulus puedo saber si el numero es impar // Manda verdadero cuando es impar return (someNumber%2 == 0) ? false : true; } function endsWithOne(someOtherNumber) { //console.log("Revisando si el numero termina con uno"); // Primero convierto el numero a string var textNumber = someOtherNumber + ""; // A los strings los puedo manipular como arreglos var textLength = textNumber.length; // Imprimo en consola el dato de textLenght //console.log("textLength: " + textLength); // Obtengo en lastCharacter el ultimo caracter de mi numero var lastCharacter = textNumber.substring(textLength,textLength - 1); // Imprimo en consola el dato de lastCharacter //console.log("lastCharacter: " + lastCharacter); // Comparo si el ultimo caracter es un uno if (lastCharacter == "1") { // Si es uno, le concateno ".1" textNumber = textNumber + ".1" // Lo convierto a un numero con punto flotante floatNumber = parseFloat(textNumber); // Imprimo en consola el dato de floatNumber //console.log("floatNumber: " + floatNumber); //console.log("El numero termina con uno, sera añadido un .1"); // Regreso el resultado como un numero flotante y añadido un ".1" return floatNumber; } else { // Si no termina en 1 el numero lo convierto de vuelta a numero y // lo regreso de vuelta intNumber = parseInt(textNumber); // Imprimo en consola el dato de intNumber //console.log("intNumber: " + intNumber); //console.log("El numero no termina con uno, continuando"); // Regreso el numero entero tal cual lo recibi return intNumber; } } // Creo una funcion que revise si el numero ya esta en mi arreglo function isInArray(array, el) { //console.log("Revisando si el numero esta en el array"); // Hago un for fijando el largo del arreglo obtenido en el parametro a la // variable j, y cada vez reviso si el elemento existe en mi arreglo. for (var i = 0, j = array.length; i < j; i++) { // en get Random le paso un numero aleatorio con el parametro "el" // Con esto reviso si el numero aleatorio ya esta en mi arreglo if (array[i] == el) { //console.log("El numero si esta en el arreglo"); // Regreso verdadero si esta en el array return true; } } // Regreso falso si no esta en el array return false; } /** * La siguiente función es recursiva (se vuelve a llamar a asi misma en el * return, por lo tanto se vuelve un poco pesada). * Creo un arreglo con longitud aleatoria multiplicada por el arreglo origen * recibido como parametro en esta funcion. * por la longitud de mi arreglo, usando la funcion isInArray reviso si los * datos ya existen o no en el arreglo origen y meten los datos * aleatoriamente en el arreglo hasta que porfin obtengo finalmente mi arreglo * con los indices aleatorios y sin repetirse. */ function getRandom(array) { //console.log("Volviendo aleatorio el arreglo"); // Defino un arreglo local con longitud aleatoria basada en la longitud // de mi arreglo origen pasado en el parametro var rand = array[Math.floor(Math.random() * array.length)]; // Si no esta en el arreglo global randomArray... if (!isInArray(randomArray, rand)) { // Lo inserto en él randomArray.push(rand); // Y regreso mi arreglo local rand generado en esta funcion return rand; } // Aqui esta la recursividad de mi funcion, se vuelve a llamar a asi // misma si está en el arreglo mi dato pasado. return getRandom(array); } /** * En esta funcion voy a obtener los numeros comprendidos entre el dato A * y el dato B, lo puedo hacer de forma simple con un ciclo for, fijando el * inicio en mi dato A (sin contar A misma) y dando como termino del ciclo * mi dato B, e irlos metiendo directamente a un arreglo llamado Z. */ function obtainNumbersInBetween(numbersArray) { //console.log("Obteniendo numeros entre A y B"); // Capturo en otro arreglo local el par de numeros que obtuve en getData() var dataArray = numbersArray; // Registro en consola los datos de mi arreglo local. //console.log("Contenido de validatedDataArray: " + dataArray); // Reviso que el array recibido en el parametro este definido, si no esta // definido mando un mensaje de error al usuario. if (typeof dataArray == "undefined") { // Añado un span con el mensaje de error $("#msgSubmit").append("<br /><span class'error' " + "id='msgUndefinedArray'>El array no fue salvado.</span>"); return false; } // Guardo en dos variables los datos obtenidos en getData() var dataA = dataArray[0]; //console.log("Valor de dataA: " + dataA); var dataB = dataArray[1]; //console.log("Valor de dataB: " + dataB); // Inicializo vacio un arreglo local llamado conso var arrayZ = []; // Inicializo la variable que usare dentro de mi ciclo for para capturar // el resultado de la funcion endsWithOne() var oneEnding; // Poblo inicialmente ciclo for con mi dato A como inicio y mi dato B // como el final. Internamente reviso 3 de las condiciones: // - a) Solo deben estar los numeros nones // - c) No se pueden repetir los numeros (porque son secuenciales) // - d) A todos los numeros que terminen en 1 (1, 11, 21, 31, ...) // sumarles 0.1 // La condicion B la reviso con las dos funciones getRandom() e isInArray(); for (i = dataA + 1, j = dataB; i < j; i++) { if (isOddNumber(i)) { var data = endsWithOne(i); arrayZ.push(data); } } // El array que obtengo lo reviso al final del for //console.log("Valor de arrayZ tras el for: " + arrayZ); return arrayZ; } // Cuando la página ha sido cargada exitosamente ejecuta el siguiente script $(document).ready(function () { //console.log("Iniciando script"); /** * Creo una funcion dummy no operativa para evitar problemas con * javascript al no tener firebug instalado y activado. * Si la funcion console es de tipo indefinida, defino una funcion * anonima que no recibe argumentos y no hace nada. * Con esto evito que no se ejecute el javascript cuando firebug no * está activado. */ if(typeof console === "undefined") { console = { log: function() { } }; } /** * Cuando le de click al boton de submit capturara los datos de los * inputs en dos variables A y B, posteriormente obtiene los numeros * comprendidos entre estos dos numeros. */ // Cuando envio el submit de la forma ejercicio haz lo siguiente: $("#ejercicio").submit(function (){ // Vacio el contenido de result $("#result").html(""); // Mando llamar la funcion getData la cual captura los datos // Y paso a otro array el resultado del return. var resultingArray = getData(); var textoNuevo = "<p>Los numeros que ha introducido son</p><br />" + "<p>Numero A = " + resultingArray[0] + "</p>" + "<p>Numero B = " + resultingArray[1] + "</p>"; $("#submit").html(textoNuevo); // Creo el arreglo donde insertare el arreglo resultante var arrayToRandomize = []; // Obtengo el arreglo donde reviso tres de las cuatro // condiciones (a,c y d) arrayToRandomize = obtainNumbersInBetween(resultingArray); // Finalizando el script, imprimo estados finales: //console.log("Imprimiendo resultado en pantalla (HTML)"); //console.log("Esto puede tardar un poco..."); $("#result").append("<li>Nuevos datos:</li>"); // Imprimo finalmente mi arreglo aleatoro. for (k = 0; k < arrayToRandomize.length; k++) { // Realizo la ultima condicion (b) randomizando el arreglo. // Aqui puede estar el cuello de botella en el script // Imprimo en el HTML mis resultados $("#result").append("<li>" + getRandom(arrayToRandomize) + "</li>"); } //console.log("Proceso terminado"); // Vacio el array cada vez que le da click para que no haya un leak // de memoria cuando vuelvo a llamar el metodo getRandom() randomArray = []; // Envio false para que no me refresque la pagina return false; }); }); </script> </body> </html>
URL: pruebaHS