elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Como proteger una cartera - billetera de Bitcoin


  Mostrar Mensajes
Páginas: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [16] 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ... 86
151  Programación / Programación General / Re: Simbología y elementos de un diagrama de clases en: 5 Junio 2020, 15:01 pm
La flecha de Empleado es una relación de Generalización.

Si has trabajado con programación orientada a objetos es la herencia de toda la vida. Lo que quiere decir es que Cuidador y Guía heredan (se especializan) de Empleado. O dicho al revés que Empleado es una generalización de Cuidador y Guía. Se habla de generalización/especialización según si lo miras en un sentido o en otro.

Esto se usa cuando varias clases tienen aspectos en común para no escribirlos dos veces (una vez en cada clase) se hace una superclase (o clase padre) que engloba estos aspectos comunes. Al final el resultado es que si una clase (hija) hereda/se especializa de una clase (padre), la clase hija contendrá de forma implícita todos los atributos y comportamientos (métodos) de la clase padre.

Prácticamente siempre si no siempre se tiene que poder leer como: <clase hija> ES UN <clase padre>. Ejemplos:
  • Cuidador ES UN Empleado.
  • Guía ES UN Empleado.
152  Programación / Programación C/C++ / Re: problema if anidados (notas) en: 5 Junio 2020, 14:55 pm
El problema está en esos ".9".
En ningún momento aseguras que la nota tenga un solo decimal, entonces qué pasa si tienes un 9.95, 9.995, 9.999995, 6.99999999??? Todas esas notas no están contempladas en ningún caso.

Es por esto que no se usa (<= 9.9) sino que se usa (< 10) que sí contempla cualquier cantidad de decimales. Así que tendrías que sustituirlo en todos los casos y cuando sustituyas (<= 6.9) por (< 7) verás que funciona correctamente. El problema será que aunque tú escribas 6.9, un float (32 bits) maneja una cantidad muy grande de decimales, entonces es posible que se guarde 6.90[...]01 y entonces no se cumple la condición.

Aparte de eso, te doy algún consejo más aunque no te frustres por no haber hecho el mejor programa. Es normal cuando uno está empezando. Poco a poco irás mejorando en la lógica.
  • Para limpiar el buffer no se debe utilizar nunca fflush(stdin). Esta función está definida por el lenguaje para limpiar el buffer de salida (fflush(stdout)) y hasta la propia documentación del lenguaje recoge que el uso con stdin es indeterminado. Puede ser que 1 millón de veces pero no hay fundamentación teórica que diga que va a funcionar 1 millón y 1 vez.
Una alternativa para limpiar el buffer es:
Código
  1. while(getchar() != '\n');
Por si te interesa el funcionamiento: el buffer contiene lo que introduces por teclado para luego usarlo (en una asignación a una variable por ejemplo). Puede ser que queden caracteres que no cabían en la variable y al final como último elemento del buffer el ENTER ('\n'). Con la instrucción anterior vas cogiendo cada caracter que queda en el buffer hasta encontrar el ENTER (que lo coge también). Una vez cogido el ENTER, ese bucle termina y el buffer está vacío.

  • Si ordenas los rangos de los ifs verás que queda un código más simple y con menos condiciones. Además los else-if se suelen encadenar como te muestro acontinuación pues es más fácil de leer y ahorran llaves:
Código
  1. if(nota < 0){
  2.  printf("La nota es menor que 0. Intervalo: (-inf,0)");
  3. } else if(nota < 5){ // Si llegamos a este else, la condicion anterior es falsa por lo tanto ya sabemos que el numero es >= 0. No hay que comprobarlo otra vez
  4.    printf("La nota esta entre 0 y 5 sin llegar al 5. Intervalo: [0,5)");
  5.  } else if(nota < 7){ // Si llegamos aqui ya sabemos que nota >= 0 por el primer if y que nota >= 5 por el segundo. No hay que comprobarlo.
  6.      printf("La nota esta entre 5 y 7 sin llegar al 7. Intervalo: [5,7)");
  7.    } else if(nota < 9){ // Igual que antes. Ya sabemos que la nota es >= 7.
  8.         printf("La nota esta entre 7 y 9 sin llegar al 9. Intervalo: [7,9)");
  9.       } else if(nota < 10){ // Ya sabemos que la nota es >= 9
  10.            printf("La nota esta entre 9 y 10 sin llegar al 10. Intervalo: [9,10)");
  11.          } else if(nota == 10){
  12.               printf("La nota es 10");
  13.             } else { // Igual que antes si ninguno de los ifs anteriores se han cumplido, ya sabemos que la nota es > 10
  14.                  printf("La nota es mayor que 10. Intervalo: (10, +infinito)");
  15.                }

Si has utilizado los intervalos de matemáticas puedes ver la diferencia de usar intervalo abierto o cerrado. En la mitad abierta (con paréntesis) no se incluye ese valor pero en la cerrada (con corchetes), sí. Ese matiz es la diferencia entre usar el < / > o el <= / >=.

Además suele quedar un poco feo eso de que el código se vaya tanto hacia el centro y cuando los bloques (condicionales, bucles,...) están formados por una única línea en su interior se pueden omitir las llaves. Muchas veces lo verás así:
Código
  1. if(nota < 0)
  2.  printf("La nota es menor que 0");
  3. else if(nota < 5)
  4.  printf("La nota esta entre 0 y 5");
  5. else if(nota < 7)
  6.  printf("La nota esta entre 5 y 7");
  7. //...

PD: Por otra parte, muy bien usado el getchar() al final para hacer una pausa en vez de utilizar getch() o system("pause"). ;-)
153  Programación / Programación General / Re: Simbología y elementos de un diagrama de clases en: 5 Junio 2020, 13:20 pm
Los rombos con relleno (los únicos que aparecen en tu diagrama) representan una relación de composición.
La característica de estas relaciones es que determina una entidad débil (Parque) y una entidad fuerte (Zona). La entidad débil no puede existir por sí misma sin la entidad fuerte, es decir, que no puedes guardar los parques de una zona en tu sistema si no tienes guardada esa zona. De igual manera entre Zoo - Parque, no puedes guardar en tu sistema los Zoos de un parque si no tienes guardado ese parque.
Otra característica es que una instancia de la entidad débil no puede ser compartida por varias de la fuerte. Un Zoo no puede pertenecer a varios parques diferentes.
Y una última característica sería que si en algún momento eliminas la instancia de la entidad fuerte, se deberán eliminar todas las instancias de la entidad débil que estuviesen relacionadas con esa instancia de la fuerte. Resumido: Si en tu sistema eliminas un parque, se deberán eliminar primero todos los zoos de ese parque.

Existe otro tipo de rombo que no está relleno y estos representan relaciones de agregación. Son un poco "la otra mitad":
También podemos diferenciar una entidad débil y una fuerte, y que la débil forma parte de la fuerte, pero en este caso no existe una dependencia tan fuerte como en el caso anterior.
En este caso una instancia de la entidad débil puede estar relacionada con más de una instancia de la entidad fuerte.
Si se elimina la instancia de la entidad fuerte, no se eliminan las instancias de la entidad débil con las que tuviese relación.
Por ejemplo: En un taller, Piezas - Vehículos. Tienen unas piezas guardadas en un almacén y esas piezas se usan para reparar unos vehículos. Pero cuando el vehículo sale del sistema, no tiran todas las piezas que valían para ese vehículo, siguen ahí para utilizarlas con otro.
154  Programación / Programación C/C++ / Re: Me pueden explicar como hago estos problemas! por favor. en: 5 Junio 2020, 01:36 am
No sé si estás programando en C o en C++. Te dejo un pseudocódigo para que intentes implementarlo en el lenguaje que uses:
Código:
// Un filtro para pedir el tamaño de la matriz A:
HACER
  PEDIR filasA, columnasA
  valido = filasA < 1 or filasA > 10 or columnasA < 1 or columnasA > 10
  SI !valido ENTONCES
    MOSTRAR "Error: El tamaño de la matriz no es valido"
  FIN SI
MIENTRAS !valido
matrizA[filasA][columnasA]
// Repetir lo mismo para la matriz B pero en este caso tendras que comprobar tambien que se cumpla la segunda condicion

matrizResultado[filasA][columnasB]
matrizResultado = multiplicar(matrizA, matrizB)

Ahora intenta codificar eso hasta donde llegues. Por lo menos hasta la parte de la matrizResultado tienes que poder llegar.
En cualquier caso si tienes algún problema y te estancas, coloca tu código entre etiquetas de Código GeSHi eligiendo el lenguaje adecuado (C/C++) y así viendo cómo lo llevas podremos guiarte mejor.

Suerte. :-X
155  Programación / Bases de Datos / Re: Trigger complejos MySQL en: 4 Junio 2020, 19:23 pm
Para empezar ese trigger salta después de la inserción por lo que aunque no sea válido el registro, ya estará insertado. Tiene que ser before.

Además no vale eso de producto.stock y ya. Cuando insertas un registro en Inventario, los campos que introduces son: id_pedido, id_producto, cantidad. Ninguno de ellos es stock. Así que lo que tienes que hacer es una consulta a la tabla Producto para obtener el registro asociado a ese id_producto.
156  Programación / Bases de Datos / Re: Trigger complejos MySQL en: 4 Junio 2020, 15:16 pm
Veo que el código que has puesto al comienzo del tema está completado en base a mi respuesta de este otro tema: https://foro.elhacker.net/bases_de_datos/pasar_a_mysql-t505018.0.html;msg2222689#msg2222689, lo que me hace pensar que no estás empleando ningún esfuerzo en hacerlo por ti mismo.

El foro es para ayudar, no para hacer tareas. No puedes esperar que te den todos los problemas solucionados porque en algún momento de tu vida tendrás que hacerlo tú solo y entonces no sabrás ni por dónde empezar.

Ya tienes un punto de referencia para saber por donde empezar, además tienes muchísima información tanto en otros temas del foro como en Internet sobre cómo hacer triggers.

Inténtalo tú e investiga sobre los problemas que tengas. Y cuando no encuentres información o no entiendas cómo solucionar un problema, aporta tu código para que alguien de la comunidad pueda ayudarte.
157  Programación / Bases de Datos / Re: [Pregunta]: Eliminar una clave foránea. en: 4 Junio 2020, 11:43 am
En MySQL:
Código
  1. ALTER TABLE <tabla con la FK> DROP FOREIGN KEY <nombre de la FK>;

En SQL Server / Oracle / MS Access:
Código
  1. ALTER TABLE <tabla con la FK> DROP CONSTRAINT <nombre de la FK>;
158  Programación / Bases de Datos / Re: Trigger complejos MySQL en: 4 Junio 2020, 11:33 am
Los triggers son:
1.Trigger que al introducir una fila en la tabla que nace de la relación entre pedido y producto (inventario) , compruebe que en la tabla producto hay stock y sino tiré un warning.
En este caso puedes crear un trigger BEFORE INSERT que compruebe lo que tú dices y en caso de que no sea válido puedes ejecutar:
Código
  1. SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Insercion no valida...'
Te dejo un link para que leas más acerca de ello: https://dev.mysql.com/doc/refman/8.0/en/signal.html

2.Trigger que tras introducir un nuevo producto compruebe que el precio es mayor que 0. Si es menor o igual a 0, el trigger deberá eliminar el artículo que se ha insertado.
De la misma forma que antes. En vez de insertar el producto y después de la inserción, comprobar la validez del mismo; puedes usar un trigger BEFORE INSERT y lanzar otro error si no se cumple la condición de validez del registro.
159  Programación / Programación C/C++ / Re: Agenda telefonica en: 4 Junio 2020, 11:17 am
Sigue siendo un poco lío ese código... Las funciones tienen que tener un valor de retorno aunque este sea void, la función main() está vacía, es difícil seguir con precisión la ejecución si se va pasando de función en función, algunas funciones hacen demasiadas cosas...
Te pongo una estructura alternativa para que la rellenes:
Código
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdbool.h>
  4.  
  5. // Declara constantes para los numeros que vayas a usar luego. Si siguen algun patron que poner de nombre para recordarlos mejor, usalo.
  6. // Si las longitudes que utilizas estan fundamentadas en algo no dire nada pero si son aleatorias te recomiendo que utilices una para todo. O las minimas necesarias, por ejemplo: LONG_NOMBRE y LONG_OTRAS_CADENAS o lo que mas te convenza
  7. #define LONG_NOMBRE 20
  8. #define LONG_OTRAS_CADENAS 15
  9. #define MAX_CONTACTOS 30
  10.  
  11. // Crea un tipo de dato Contacto que consta de un struct. Los campos es mejor poner uno por linea.
  12. // Si no quieres usar typedef cambialo por struct Contacto {...} pero tendras que usar "struct Contacto" cada vez que quieras hacer referencia a "Contacto"
  13. typedef struct {
  14. int numeroRegistrado; // Este campo no podras relacionarlo con el numero de contactos porque al borrar uno se produciran saltos y se repetiran valores.
  15. //int activo; // Por lo que veo lo usas para determinar si el numero esta borrado o no. Para este codigo es prescindible, ya lo veras.
  16. int telefono; // Dudo que realmente necesites un long para un telefono asi que usare int durante todo el codigo
  17. char nombre[LONG_NOMBRE];
  18. char apellidoPaterno[LONG_NOMBRE]; // Que no te de miedo poner nombres un poco largos. Cuanto mejor se entienda, mejor
  19. char apellidoMaterno[LONG_NOMBRE];
  20. //...
  21. } Contacto; // No declares el array global
  22.  
  23. int main(){
  24. Contacto contactos[MAX_CONTACTOS]; // Declara el array local
  25. int contactosRegistrados = 0;
  26. int telefonoBuscado;
  27. int indiceBuscado;
  28. int opcion;
  29. do {
  30. opcion = mostrarMenu(); // Muestra el menu y devuelve la opcion. En mostrarMenu() puedes controlar que la opcion este en el rango
  31. switch(opcion){
  32. case 1:
  33. if(contactosRegistrados < MAX_CONTACTOS){
  34. contactos[contactosRegistrados] = crearContacto(); // Crea un contacto en el array contactos en la posicion contactosRegistrados
  35. ++contactosRegistrados;
  36. } else printf("Limite de contactos alcanzado\n");
  37. break;
  38.  
  39. case 2: // Cuando actualizas es como si creases un contacto nuevo en la posicion del existente
  40. printf("Introduce el numero de telefono del contacto a modificar: ");
  41. scanf("%d", &telefonoBuscado);
  42. while(getchar() != '\n');
  43. indiceBuscado = buscarPorTelefono(contactos, contactosRegistrados, telefonoBuscado); // Que devuelva el indice del contacto con ese numero o -1 si no lo encuentra
  44. if(indiceBuscado != -1){
  45. contactos[indiceBuscado] = crearContacto();
  46. } else printf("No existe ningun contacto con ese numero\n");
  47. break;
  48.  
  49. case 3: // Para borrar de un array lo que se hace es mover todos los elementos a la derecha del eliminado una posicion hacia la izquierda para no dejar huecos
  50. printf("Introduce el numero de telefono del contacto a eliminar: ");
  51. scanf("%d", &telefonoBuscado);
  52. while(getchar() != '\n');
  53. indiceBuscado = buscarPorTelefono(contactos, contactosRegistrados, telefonoBuscado); // Que devuelva el indice del contacto con ese numero o -1 si no lo encuentra
  54. if(indiceBuscado != -1){
  55. eliminarContacto(contactos, contactosRegistrados, indiceBuscado); // Que empiece en indiceBuscado y hasta el final mueva cada contactos a su izquierda
  56. --contactosRegistrados;
  57. } else printf("No existe ningun contacto con ese numero\n");
  58. break;
  59. }
  60. mostrarContactos(contactos, contactosRegistrados);
  61. } while(opcion != 4); // La opcion 4 solo sale. No es necesario hacer un case para ella.
  62. // Para hacer una pausa olvidate de getch() y de system("pause"). La mejor opcion SIEMPRE es getchar() que pertenece a <stdio.h> asi que olvidate de <conio.h>
  63. return 0;
  64. }

Como ves, la función main() tiene que dar una idea general del funcionamiento del programa. Que al mirar el main() puedas saber lo que hace el programa aunque no sepas cómo (esto corresponde a las funciones adicionales).
Crea funciones estructuradas, no que se llamen unas a otras haciendo bucles o que tengan varios return (hay casos excepcionales pero son pocos).
Ahora te queda a ti implementar las funciones que he ido llamando por ahí. Créalas de forma que cumplan las restricciones que te pongo y todo funcionará correctamente. Observa también los parámetros que tienen que tener y sus valores de retorno. Y limítate a que cada función realice su labor, no quieras mezclar. Cuanto más precisa sea una función más independiente será y más la podrás reutilizar (fíjate en buscarPorTelefono() o crearContacto() como las hemos podido usar varias veces).

Casi lo olvido: para solucionar el tema del numeroRegistro de cada contacto, puedes crear dentro de la función crearContacto() una variable static. Las variables static mantienen su existencia y su valor durante las diferentes llamadas a la función. Así cada vez que llames a la función puedes incrementar en 1 esa variable y en la siguiente llamada, se mantendrá ese valor para volver a incrementarle 1.

Ya tienes bastante trabajo. Y te aseguro si te sirve de inspiración que vas a aprender/reforzar bastantes cosas de hacer este programa. Dos consejos más para que por favor apliques y te quede ya un programa de 10, te lo aseguro:
  • Leer cadenas de texto: Para esto la función recomendada es fgets(). Por ejemplo, para guardar el nombre (que te hará falta):
Código
  1. Contacto contacto;
  2. printf("Introduce el nombre: ");
  3. fgets(contacto.nombre, LONG_NOMBRE, stdin);
Una vez guardado el nombre es importante hacer dos cosas más: eliminar el salto de línea que se habrá almacenado al pulsar ENTER y limpiar el buffer para el siguiente dato que pidamos. Para hacer ambas cosas utiliza el siguiente código justo después del fgets():
Código
  1. if(contacto.nombre[strlen(contacto.nombre)-1] == '\n') // Si antes del final de cadena hay un salto de linea...
  2.    contacto.nombre[strlen(contacto.nombre)-1] = '\0'; //... lo sustituimos por el final de cadena para eliminarlo
  3. else // sino, el salto de linea se ha quedado en el buffer ademas de que puede haber otros caracteres antes...
  4.    while(getchar() != '\n'); // ...entonces con esto limpiamos el buffer en caso de que quede algo
Como puedes ver en las funciones scanf() de más arriba también he utilizado la misma sentencia para limpiar el buffer pero en ese caso sin la comprobación del if pues el scanf() siempre deja el ENTER en el buffer.
Esta es una manera más correcta de limpiar el buffer que con fflush(stdin). Utilízalo.

Cualquier duda, problema o lo que sea que tengas, no dudes en preguntar. El objetivo es que entiendas lo que se hace y por qué.

Suerte. :-X
160  Programación / Programación C/C++ / Re: Ayudaaa en: 4 Junio 2020, 10:19 am
Tienes que representar 3 estados por lo que si lo calculas todo dentro de la función no podrás usar como valor de retorno <bool>. Para poder usar un <bool> tienes que separar la lógica del problema, por ejemplo, haciendo una función que te devuelva true/false según si el mensaje está en la cadena o no y llamar a esta función dos veces, la segunda vez con la cadena invertida.

El resultado podría ser algo así:
Código
  1. #include <iostream>
  2. #include <string>
  3. #include <algorithm>
  4.  
  5. using namespace std;
  6.  
  7. bool contieneMensaje(string cadena, string mensaje){
  8. size_t posicion = cadena.find(mensaje);
  9. return posicion != string::npos;
  10. }
  11.  
  12. int main(){
  13. string cadena = "ABDLFJKDSHKHLIDFNMENSAJESJDSKFJSDFNISDFJDFSLKJDFSLDFS";
  14. string mensaje = "MENSAJE";
  15. string direccion = "Derecha - Izquierda"; // Por defecto asumimos que la direccion es esa para solo cambiarla una vez
  16.  
  17. bool encontrado = contieneMensaje(cadena, mensaje);
  18.        // Si la cadena la encontramos a la primera, esta en la otra direccion
  19. if(encontrado) direccion = "Izquierda - Derecha";
  20. // Invertimos la cadena y volvemos a usar la funcion
  21. string cadenaInvertida = string(cadena.rbegin(), cadena.rend());
  22.        // Para que se guarde true tanto si lo era antes como si lo es ahora usamos un OR |.
  23. encontrado |= contieneMensaje(cadenaInvertida, mensaje); // Equivale a: encontrado = encontrado || contieneMensaje(...)
  24.  
  25. if(encontrado) cout << "Si" << endl << direccion << endl;
  26. else cout << "No" << endl;
  27. }
Páginas: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [16] 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ... 86
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines