Foros del Web » Programando para Internet » PHP »

Algoritmo en PHP

Estas en el tema de Algoritmo en PHP en el foro de PHP en Foros del Web. Hola a todos, Quisiera que por favor me ayudaran a entender qué hace realmente la siguiente función en PHP, ya que me salió e un ...
  #1 (permalink)  
Antiguo 12/05/2014, 07:27
 
Fecha de Ingreso: marzo-2005
Mensajes: 309
Antigüedad: 19 años, 1 mes
Puntos: 1
Algoritmo en PHP

Hola a todos,

Quisiera que por favor me ayudaran a entender qué hace realmente la siguiente función en PHP, ya que me salió e un examen y no supe qué responder:

Código PHP:
public static function is_valid($str
{
  if (!
ctype_digit($str)) return FALSE;
  
$len strlen($str);
  if (
$len != 15) return FALSE;
  
$odd = !strlen($str)%2;
  
$sum 0;
  for (
$i=0$i<$len; ++$i) {
    
$n $str[$i];
    
$odd = !odd;
    if (
$odd) {
      
$sum += $n;
    } else {
      
$x=2*$n;
      
$sum += $x>9?$x-9:$x;
    }
  }
  return ((
$sum%10)==0);

Muchas gracias por su tiempo.
  #2 (permalink)  
Antiguo 12/05/2014, 08:08
Avatar de guardarmicorreo  
Fecha de Ingreso: noviembre-2012
Ubicación: Córdoba
Mensajes: 1.153
Antigüedad: 11 años, 5 meses
Puntos: 84
Respuesta: Algoritmo en PHP

¿Qué es lo que no entiendes?
__________________
Ayúdame a hacerlo por mi mismo.
  #3 (permalink)  
Antiguo 12/05/2014, 08:15
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: Algoritmo en PHP

Si miras que funciones utiliza ya te das una idea de lo hace :)

Verifica que sea una cadena de numeros de longitud igual a 15 o sea ([0-9]{15}) y luego en base a si el numero de caracteres es par o impar(odd) hace una cuenta y devuelve ese valor
__________________
Salu2!
  #4 (permalink)  
Antiguo 12/05/2014, 09:30
 
Fecha de Ingreso: marzo-2005
Mensajes: 309
Antigüedad: 19 años, 1 mes
Puntos: 1
Re: Algoritmo en PHP

Hola chicos,

Gracias por responder.

Lo que no entiendo es cual es el objetivo de la función. Evidentemente se aseguran de que sea un número no superior a 15 caracteres, luego en base a si es par o no hacen unos cálculos, pero no entiendo cual es el objetivo de la función.

Gracias
  #5 (permalink)  
Antiguo 12/05/2014, 10:01
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: Algoritmo en PHP

El objetivo es que tu puedas seguir un programa y entenderlo...nada mas ;)
__________________
Salu2!
  #6 (permalink)  
Antiguo 12/05/2014, 10:12
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Re: Algoritmo en PHP

Cita:
Iniciado por Vanessita Ver Mensaje
Hola chicos,

Gracias por responder.

Lo que no entiendo es cual es el objetivo de la función. Evidentemente se aseguran de que sea un número no superior a 15 caracteres, luego en base a si es par o no hacen unos cálculos, pero no entiendo cual es el objetivo de la función.

Gracias
Como te dicen, si esto te salió en un examen, el objetivo es múltiple: Primero, que seas capaz de analizar la lógica de una codificación que no es la tuya, para lo cual debes ver, analizar y deducir cada paso.
En segundo lugar, se aseguran de que nos eas un alumn@ que hace copy+paste. Cuando sólo copias y pegas, nunca te fijas si el algoritmo de lo que pegas es funcional, o incluso razonable. En este foro vienen muchos que preguntan cosas que son evidentes, simplemente porque no alcanzan a ver lo que tienen delante de sus ojos.
Finalmente, como persona que trabaja en desarrollo, te comento que analizar códigos ajenos es una de las tareas constantes cuando estás en alguna emrpesa. Permanentemente tienes que sufrir esos códigos mal hechos, peor mantenidos y nulamente documentados. Si no eres capaz de seguir la lógica de un algoritmo simple, ni te digo los dolores de cabeza que tendrás cuando debas reparar los de otros...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 12/05/2014, 14:49
Avatar de guardarmicorreo  
Fecha de Ingreso: noviembre-2012
Ubicación: Córdoba
Mensajes: 1.153
Antigüedad: 11 años, 5 meses
Puntos: 84
Respuesta: Algoritmo en PHP

para delimitar el objetivo de esta función (en realidad método) debes fijarte en cuantos return tiene (mal hechos, ya que solamente debería haber un return para cumplir con el PSR).

porque en realidad este método tiene varias funciones asignadas, no es simple. ahí será cuando empieces a entender lo que quieres, a partir de ahí solo te queda ir leyendo el código de arriba hacia abajo siguiendo cada instrucción y línea.
__________________
Ayúdame a hacerlo por mi mismo.
  #8 (permalink)  
Antiguo 13/05/2014, 07:14
Avatar de dashtrash
Colaborador
 
Fecha de Ingreso: abril-2007
Ubicación: Ni en Sevilla,ni en Sanlúcar..qué más da..
Mensajes: 927
Antigüedad: 17 años
Puntos: 270
Respuesta: Algoritmo en PHP

Cita:
Iniciado por Vanessita Ver Mensaje
Hola a todos,

Quisiera que por favor me ayudaran a entender qué hace realmente la siguiente función en PHP, ya que me salió e un examen y no supe qué responder:

Código PHP:
public static function is_valid($str
{
  if (!
ctype_digit($str)) return FALSE;
  
$len strlen($str);
  if (
$len != 15) return FALSE;
  
$odd = !strlen($str)%2;
  
$sum 0;
  for (
$i=0$i<$len; ++$i) {
    
$n $str[$i];
    
$odd = !odd;
    if (
$odd) {
      
$sum += $n;
    } else {
      
$x=2*$n;
      
$sum += $x>9?$x-9:$x;
    }
  }
  return ((
$sum%10)==0);

Muchas gracias por su tiempo.
Esta funcion tiene código que no es necesario, para forzar a que se esté atento a lo que hace.

Código PHP:
Ver original
  1. if ($len != 15) return FALSE;
  2.   $odd = !strlen($str)%2;
Si la longitud no es 15, la segunda línea no se ejecutará.Así que la segunda linea es equivalente a $odd=!15%2, que equivale a $odd=!1.En definitiva, $odd=0

Ahora, el bucle:
Código PHP:
Ver original
  1. for ($i=0; $i<$len; ++$i) {
  2.     $n = 0 + $str[$i];
  3.     $odd = !odd;
  4.     if ($odd) {
  5.       $sum += $n;
  6.     } else {
  7.       $x=2*$n;
  8.       $sum += $x>9?$x-9:$x;
  9.     }
  10.   }
A $n se le asigna el valor entero del caracter $i.Al ser 1 solo carácter, su valor sólo puede ser entre 0 y 9.Por lo tanto, la condicion $x>9 nunca se va a cumplir.Esto hace que el bucle quede en:
Código PHP:
Ver original
  1. for ($i=0; $i<$len; ++$i) {
  2.     $n = 0 + $str[$i];
  3.     $odd = !odd;
  4.     if ($odd) {
  5.       $sum += $n;
  6.     } else {
  7.       $x=2*$n;
  8.       $sum += $x;
  9.     }
  10.   }

Hay que tener en cuenta que $odd se inicializó a 0.En la primera iteración del blucle, $i = 0, pero $odd= !$odd, con lo que $odd pasa a ser 1.
Asi que, $sum es la suma de los numeros colocados en una posicion par, más el doble de la suma de los numeros colocados en una posicion impar. (Las posiciones se cuentan de izquierda a derecha).

La función retorna true si $sum es múltiplo de 10.
  #9 (permalink)  
Antiguo 13/05/2014, 07:53
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: Algoritmo en PHP

@dashtrash : no tiene codigo innecesario como Ud dice... Ud asume que jamas se le puede suministrar una precondicion correcta a esa funcion ? o tiene problema porque estan en distintas lineas los chequeos de cada una ?

Sino se van cumpliendo las precondiciones lo devuelve con false, eso no esta "mal" solo que como dice @guardamicorreo no cumple la recomendacion PSR de un solo return()

De todas formas podria ir chequeando precondiciones y sino se cumplen, generar las excepciones correspondientes, lo cual no esta mal si se hacen todos los chequeos al inicio de la funcion o metodo y es como esta hecho:

Código PHP:
Ver original
  1. if (!ctype_digit($str)) return FALSE;
  2.   $len = strlen($str);
  3.   if ($len != 15) return FALSE;


Por que no agrupar las precondiciones en un solo IF() al comienzo de la funcion ?

Código PHP:
Ver original
  1. if ( (!ctype_digit($str)) OR  (strlen($len) != 15) ) return FALSE;

Seria ineficiente (no mucho pero suponiendo nos importa) porque luego NECESITO la longitud de la cadena para seguir con el algoritmo y deberia volver calcularla!

Otra opcion seria:

Código PHP:
Ver original
  1. $len = strlen($str);
  2.  if (!ctype_digit($str)) return FALSE;
  3. if ($len != 15) return FALSE;

<< pero esta peor porque sino son cadenas de numeros para que voy a calcularle la longitud ? encima empujo la verificacion de la primera precondicion mas adentro de la funcion!


Y finalmente... si fuera testarudo y agrupara las verificaciones en una sola linea y luego me dicen que desean que esa funcion genere excepciones me tocaria refactorizar porque son excepciones distintas (si me importa algo claro):

Código PHP:
Ver original
  1. <?php
  2.  
  3. public static function is_valid($str,$error=false)  
  4. {  
  5.   if (!ctype_digit($str))
  6.     if ($error)
  7.         throw new InvalidArgumentException("La cadena no es numerica!");  
  8.     else return False; 
  9.  
  10.   $len = strlen($str);
  11.   if ($len != 15)  
  12.     if ($error)
  13.         throw new LengthException("Longitud incorrecta!");  
  14.     else return False; 
  15.    
  16.   $odd = !strlen($str)%2;
  17.   $sum = 0;
  18.   for ($i=0; $i<$len; ++$i) {
  19.     $n = 0 + $str[$i];
  20.     $odd = !odd;
  21.     if ($odd) {
  22.       $sum += $n;
  23.     } else {
  24.       $x=2*$n;
  25.       $sum += $x>9?$x-9:$x;
  26.     }
  27.   }
  28.   return (($sum%10)==0);
  29. }
__________________
Salu2!

Última edición por Italico76; 13/05/2014 a las 08:30
  #10 (permalink)  
Antiguo 13/05/2014, 09:22
Avatar de dashtrash
Colaborador
 
Fecha de Ingreso: abril-2007
Ubicación: Ni en Sevilla,ni en Sanlúcar..qué más da..
Mensajes: 927
Antigüedad: 17 años
Puntos: 270
Respuesta: Algoritmo en PHP

Cita:
Iniciado por Italico76 Ver Mensaje
@dashtrash : no tiene codigo innecesario como Ud dice... Ud asume que jamas se le puede suministrar una precondicion correcta a esa funcion ? o tiene problema porque estan en distintas lineas los chequeos de cada una ?
Sino se van cumpliendo las precondiciones lo devuelve con false, eso no esta "mal" solo que como dice @guardamicorreo no cumple la recomendacion PSR de un solo return()
Por supuesto que tiene código innercesario.Es innecesario llamar 2 veces a strlen, sobre todo, cuando ya se ha forzado la precondicion.Yo entiendo que a la gente le gusten los "estándares" y las "buenas prácticas", pero no se puede responder a todo con "estándares" y "buenas prácticas", sobre todo cuando no es el tema de la pregunta.

Más poquito a poco, a ver si asi está claro:
Código PHP:
Ver original
  1. $len = strlen($str);
  2.   if ($len != 15) return FALSE;
  3.   $odd = !strlen($str)%2;
La tercera linea es una *asignacion*, no es ningún chequeo de precondición, y es un código absolutamente innecesario, y es equivalente a $odd=0;
Esto no es una cuestión formal, ni de recomendaciones, ni de PSR.Es una cuestión de pura y sencilla lógica.
El código anterior equivale a:
Código PHP:
Ver original
  1. $len = strlen($str);
  2.   if ($len != 15) return FALSE;
  3.   $odd = !$len%2;
Pero, como len debe valer 15, porque si no, no estaríamos en la función, el código equivale a
Código PHP:
Ver original
  1. $odd = !(15%2);
Lo cual equivale a
Código PHP:
Ver original
  1. $odd = 0;

Código *equivalente* no tiene nada que ver con las "precondiciones".No hay ningún test ahí.
Es código escrito con el único propósito de que el alumno entienda la *lógica*, y aplique la misma...no los "estándares".
No se le pide que reescriba el código lanzando excepciones.No se le pide que adapte el código al "estandar" psr, ni que haga echos, ni nada de eso.
Se pide que se encuentre la lógica de la función.

Todo el bucle se resume en
Código PHP:
Ver original
  1. for ($i=0; $i<$len; ++$i)
  2.    $sum+=$str[$i]*(1+$i%2);
Así que...sí, sobra bastante código

Última edición por dashtrash; 13/05/2014 a las 09:48
  #11 (permalink)  
Antiguo 13/05/2014, 09:49
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: Algoritmo en PHP

@dashtransh ya entendi si punto respecto de ... ;)

Código PHP:
Ver original
  1. $odd = !(15%2);



y tiene razon excepto en que $odd no vale 0 sino false

--
En PHP false no se puede convertir en 0 como en otros lenguajes, ni existe funcion para hacer el casting y si se hiciera generaria inconcistencias seguramente.

Código PHP:
Ver original
  1. <?php
  2.  
  3. $b = 0;
  4. var_dump ($b===false);  // false
__________________
Salu2!

Última edición por Italico76; 13/05/2014 a las 09:54
  #12 (permalink)  
Antiguo 13/05/2014, 10:33
Avatar de dashtrash
Colaborador
 
Fecha de Ingreso: abril-2007
Ubicación: Ni en Sevilla,ni en Sanlúcar..qué más da..
Mensajes: 927
Antigüedad: 17 años
Puntos: 270
Respuesta: Algoritmo en PHP

Cita:
Iniciado por Italico76 Ver Mensaje
En PHP false no se puede convertir en 0 como en otros lenguajes, ni existe funcion para hacer el casting y si se hiciera generaria inconcistencias seguramente.
Es exactamente lo contrario.

Código PHP:
Ver original
  1. $a=false;
  2. echo $a+1;

El resultado es 1.

Código PHP:
Ver original
  1. $a=true;
  2. echo $a+1;
El resultado es 2

Y por si quieres algo más bonito:
Código PHP:
Ver original
  1. $a=true;
  2. echo $a."hola";

El resultado es 1hola

Por lo que no solo el casting del booleano "true" a entero es 1...Es que el casting del booleano "true" a *cadena* , es 1 !!!

*Todo* son castings implicitos.Inconsistencias?Bienvenido a PHP

El chequeo estricto de tipos (operador ===), lo *puedes* utilizar en condicionales, para forzar un chequeo de tipos.Pero la existencia de ese operador no significa que el motor de php sea tipado.
  #13 (permalink)  
Antiguo 13/05/2014, 10:36
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: Algoritmo en PHP

Vale... estaba cocinando una pasta... y editando pero me demore un poco... iba a poner esto:

@dashtransh ya entendi si punto respecto de ... ;)

Código PHP:
Ver original
  1. $odd = !(15%2);



y es cierto que si bien $odd no vale 0 sino false el resulado es el mism porque no hay comparacion con el operador identidad ni explicita ni implicitamente en funcion alguna

---
Y si... me referia entre a otras cosas a la falta de "transitividad" y a que:

Cita:
+5 == true
+1 == true
0 == false // hasta aca "ok"
-1 == true // ?????
-5 == true // ?????
Si 0 es false, los enteros negativos deberian ser todos false
__________________
Salu2!

Última edición por Italico76; 13/05/2014 a las 10:46
  #14 (permalink)  
Antiguo 13/05/2014, 10:47
Avatar de h2swider  
Fecha de Ingreso: julio-2007
Ubicación: Ciudad de Buenos Aires
Mensajes: 932
Antigüedad: 16 años, 9 meses
Puntos: 194
Respuesta: Algoritmo en PHP

Cita:
Iniciado por Italico76 Ver Mensaje
En PHP false no se puede convertir en 0 como en otros lenguajes, ni existe funcion para hacer el casting y si se hiciera generaria inconcistencias seguramente.
¿Que no se puede castear false a 0 entero?

Código PHP:
Ver original
  1. echo false  > -1; // false
  2. echo (int)false > -1; // true

Cita:
Iniciado por Italico76 Ver Mensaje
Si 0 es false, los enteros negativos deberian ser todos false
Para nada, la definición de false es justamente not true
Entonces los boleanos nacen como una mera abreviación binaria, cumpliendo con el paradigma declarativo

false, 0
true, not false

En tu ejemplo:
-1 es false?
no
entonces true

Tambien quiero remarcar mucho cuidado con los operadores AND y OR que no son lo mismo que || y &&, su operación y precedencia de ejecución son completamente distintas.
$a = 2 || 0; //boolean true
$b = 2 OR 0; //int 2
var_dump($a, $b);

$a2 = 1 && 0; //boolean false
$b2 = 1 AND 0; //int 1
var_dump($a2, $b2);
__________________
Codifica siempre como si la persona que finalmente mantedra tu código sea un psicópata violento que sabe donde vives

Última edición por h2swider; 13/05/2014 a las 11:05
  #15 (permalink)  
Antiguo 13/05/2014, 11:36
Avatar de dashtrash
Colaborador
 
Fecha de Ingreso: abril-2007
Ubicación: Ni en Sevilla,ni en Sanlúcar..qué más da..
Mensajes: 927
Antigüedad: 17 años
Puntos: 270
Respuesta: Algoritmo en PHP

Cita:
Iniciado por h2swider Ver Mensaje
$b2 = 1 AND 0; //int 1 <--- Esto no es exacto.
var_dump($a2,$b2);
Por el hecho de que AND tiene menos precedencia, es cierto que $b2 es 1, pero no que $b2 = 1 AND 0; sea 1. Es false.
En el var_dump se muestra $b2, al cual se le ha asignado 1.
Pero var_dump($a2,($b2 = 1 AND 0)) da false,false.

Entiendo lo que querias decir, pero ese comentario no era 100% exacto
  #16 (permalink)  
Antiguo 13/05/2014, 11:40
Avatar de h2swider  
Fecha de Ingreso: julio-2007
Ubicación: Ciudad de Buenos Aires
Mensajes: 932
Antigüedad: 16 años, 9 meses
Puntos: 194
Respuesta: Algoritmo en PHP

Cita:
Iniciado por dashtrash Ver Mensaje
Por el hecho de que AND tiene menos precedencia, es cierto que $b2 es 1, pero no que $b2 = 1 AND 0; sea 1. Es false.
En el var_dump se muestra $b2, al cual se le ha asignado 1.
Pero var_dump($a2,($b2 = 1 AND 0)) da false,false.

Entiendo lo que querias decir, pero ese comentario no era 100% exacto
Si totalmente exprese mal los comentarios cuando puse //1 me refería a $b2 no a la sentencia. Igualmente creo que se entendió el punto, o no?

Saludos
__________________
Codifica siempre como si la persona que finalmente mantedra tu código sea un psicópata violento que sabe donde vives
  #17 (permalink)  
Antiguo 13/05/2014, 15:10
Avatar de guardarmicorreo  
Fecha de Ingreso: noviembre-2012
Ubicación: Córdoba
Mensajes: 1.153
Antigüedad: 11 años, 5 meses
Puntos: 84
Respuesta: Algoritmo en PHP

Esto me recuerda a un debate que tuvimos dashtrash y yo el año pasado.

http://www.forosdelweb.com/f18/detec...2/#post4478677

Puede que tenga algo que ver o puede que no, pero por si acaso si sirviera de ayuda, ahí lo dejé :D un saludo a todos!
__________________
Ayúdame a hacerlo por mi mismo.

Etiquetas: Ninguno
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 10:46.