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


 


Tema destacado: ¿Usas Skype? Protégete de los Skype Resolver


  Mostrar Mensajes
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... 71
1  Programación / Programación General / Re: Simbología y elementos de un diagrama de clases en: Hoy a las 13:20
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.
2  Programación / Programación C/C++ / Re: Me pueden explicar como hago estos problemas! por favor. en: Hoy a las 01:36
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
3  Programación / Bases de Datos / Re: Trigger complejos MySQL en: Ayer a las 19:23
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.
4  Programación / Bases de Datos / Re: Trigger complejos MySQL en: Ayer a las 15:16
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.
5  Programación / Bases de Datos / Re: [Pregunta]: Eliminar una clave foránea. en: Ayer a las 11:43
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>;
6  Programación / Bases de Datos / Re: Trigger complejos MySQL en: Ayer a las 11:33
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.
7  Programación / Programación C/C++ / Re: Agenda telefonica en: Ayer a las 11:17
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
8  Programación / Programación C/C++ / Re: Ayudaaa en: Ayer a las 10:19
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. }
9  Programación / Programación C/C++ / Re: Arreglos de cadenas en C en: 3 Junio 2020, 19:51
Te lo agradezco mucho, mas o menos esta es la funcion que quería hacer pero no logro que conforme me vaya digitando el numero del nombre que desea meter al arreglo, este se vaya llenando.

Código
  1. void mostrarNombres(Persona *personas, int numeroPersonas){
  2.    int opcion,opc;
  3.    char arregloPersonas[50][LIMITE]; // limite = 100
  4.    do{
  5.        for(int i = 0; i < numeroPersonas; i++){
  6.    printf("%d Nombre: %s\n", i+1,personas[i].nombre);
  7.    printf("\n\n");
  8.   }
  9.  
  10.   printf(" Ingrese el numero correspondiente al nombre que desea: ");
  11.       scanf("%d",&opcion);
  12.  
  13.       for(int j=0; j<numeroLibros; j++){
  14.           if(opcion == j+1){
  15.               //En este caso la persona con el numero que ingrese deberia guardarse en el arreglo, y es lo que no funciona
  16.               //personas[j].nombre
  17.  
  18.           }
  19.       }
  20.  
  21.       printf(" Desea agregar otro nombre?, 1 = SI , 2 = NO: ");
  22.       scanf("%d",&opc);
  23.       system("cls");
  24.    }while(opc == 1);
  25.    if(opc == 2){
  26.        printf("\nNOMBRES AGREGADOS:\n");
  27.        for(int i=0; i<numeroPersonas;i++){
  28.             printf("%s\n",arregloPersonas[i]);
  29.        }
  30.  
  31.    }
  32.    else{
  33.        printf("ERROR, OPCION NO VALIDA");
  34.    }
  35. }

Como te ha dicho @ErahUnderground, la variable numeroLibros que utilizas no aparece definida en ningún sitio.
Me da la sensación de que querías usar numeroPersonas ya que tiene más sentido así que mi respuesta irá por esa línea.

Daré por hecho que numeroPersonas contiene la cantidad de personas almacenadas en el array personas. Entonces te falta otro índice para ir guardando en arregloPersonas ya que si no usas otro índice guardarás a la persona 40 en la fila 40 y habrás desperdiciado las anteriores filas de arregloPersonas.
El resultado sería:
Código
  1. void mostrarNombres(Persona *personas, int numeroPersonas){
  2.    int opcion;
  3.    int indicePersona; // indice de la persona a guardar
  4.    char arregloPersonas[50][LIMITE]; // limite = 100
  5.    int personasGuardadas = 0; // personas guardadas en arregloPersonas
  6.  
  7.    do {
  8.        // Otro bucle para evitar que se introduzca un indice fuera de los limites permitidos
  9.        do {
  10.            printf("Numero de la persona a almacenar [%d - %d]: ", 1, numeroPersonas);
  11.            scanf("%d", &indicePersona);
  12.        } while(indicePersona < 1 || indicePersona > numeroPersonas);
  13.  
  14.        // Ahora no tenemos que recorrer el bucle, accedemos directamente al indice:
  15.        // Para copiar cadenas, usa strncpy:
  16.        strncpy(arregloPersonas[personasGuardadas], personas[indicePersona-1], LIMITE); // Al segundo le restamos 1 porque pedimos un indice empezado en 1 pero los arrays en C empiezan en 0.
  17.        arregloPersonas[personasGuardadas][LIMITE-1] = '\0'; // Para curarme en salud y asegurarme que la cadena tiene un caracter de fin de cadena
  18.        ++personasGuardadas;
  19.  
  20.        // Si no hemos llegado al limite, le dejamos al usuario elegir:
  21.        if(personasGuardadas < 50){
  22.            // Otro bucle para que la opcion sea 1 o 2:
  23.            do {
  24.                printf("Guardar otro nombre (1 = Si / 2 = No): ");
  25.                scanf("%d", &opcion);
  26.            } while(opcion != 1 && opcion != 2);
  27.        }
  28.    } while(personasGuardadas < 50 && opcion == 1);
  29.  
  30.    // Aqui ya puedes mostrar los nombres guardados usando como limite <personasGuardadas>:
  31.    printf("Los nombres guardados son:\n");
  32.    for(int i = 0; i < personasGuardadas; ++i){
  33.        printf("%s\n", arregloPersonas[i]);
  34.    }
  35. }
10  Programación / Programación General / Re: Aplicaciones para diagramas en: 3 Junio 2020, 10:39
PÁGINAS WEB

Una muy buena alternativa si los diagramas no son muy grandes es Lucidchart. Es una página web que permite hacer infinidad de diagramas y a mí parecer con una interfaz bastante simple y amigable. Si te ves en la necesidad de hacer diagramas muy grandes puedes valorar el premium.

Otra web que te puede servir como alternativa es Vertabelo. Esta en cambio la versión gratuita solo te permite usarla un tiempo limitado con el correo registrado (siempre tienes la opción de usar otros correos... :silbar: :silbar:)

PROGRAMAS

Si utilizas algún IDE puedes buscar plugins para la creación de diagramas. En Eclipse por ejemplo sé que está Papyrus.

Otro programa pueda ser VisualParadigm pero este es de pago y la versión de prueba es de tiempo limitado.

Y si te gusta hacer las cosas muy retro pues tienes ArgoUML. Es totalmente gratuito pero tiene algunas pegas como que el proyecto está abandonado desde hace años y algunas funciones básicas como Ctrl+Z y otras no están disponibles. Pero como última opción te puede servir... :silbar:

Suerte. :-X
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... 71
Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines