Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - K-YreX

#81
Cita de: EdePC en 29 Marzo 2021, 07:40 AM
Saludos,

Supongo que estás buscando algo recomendado desde cero y muy fácil de entender, yo te recomiendo estas guías (están en español):

Módulo I. Órdenes UNIX y Shell Bash

Sesión Nº1: Introducción a un entorno gráfico de Unix
http://www.ugr.es/~benghazi/practica/Sesion1.pdf

Sesión Nº2: Órdenes de UNIX/Linux (Parte I)
http://www.ugr.es/~benghazi/practica/Sesion2.pdf

Sesión Nº3: Permisos y redirecciones
http://www.ugr.es/~benghazi/practica/Sesion3.pdf

Sesión Nº4: Variables, Alias y Órdenes de Búsqueda
http://www.ugr.es/~benghazi/practica/Sesion4.pdf

Sesión Nº5: Expresiones con variables y expresiones regulares
http://www.ugr.es/~benghazi/practica/Sesion5.pdf

Sesión Nº6: Programación del shell
http://www.ugr.es/~benghazi/practica/Sesion6.pdf

Sesión Nº7: Depuración y Control de trabajos
http://www.ugr.es/~benghazi/practica/Sesion7.pdf

Con eso ya vas a tener una buena base para manejarte en Linux y Bash

:o :o Acabo de volver 4 años atrás... Que recuerdos me acaban de venir de cuando empecé a estudiar en la UGR con estos mismos apuntes.
Recuerdo que pasé noches practicando con todos esos comandos y con algún que otro dolor de cabeza (ya no sé si sería cosa de los apuntes o porque yo no tenía ni idea por aquel entonces  :xD)

Son de los pocos apuntes en pdf que imprimí y que aún conservo.

Perdón por salirme del tema. Y mucha suerte y ánimo a los que estén empezando ahora con ello. Al final se le coge mucho cariño a la Terminal  ;D
#82
Te dejo dos opciones que te pueden servir. Ambas están sacadas del siguiente link: https://bytes.com/topic/c-sharp/answers/257251-how-detect-hard-drives

  • Opción 1
    Código (csharp) [Seleccionar]

    using System;
    using System.Runtime.InteropServices;

    public class ListDrives {
     
      public enum DriveType : int {
        Unknown = 0,
        NoRoot = 1,
        Removable = 2,
        Localdisk = 3,
        Network = 4,
        CD = 5,
        RAMDrive = 6
      }

      [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
      public static extern int GetDriveType(string s);

      public static void Main(string[] args) {
        foreach(string s in Environment.GetLogicalDrives())
          Console.WriteLine(string.Format("Drive {0} is a {1}", s, Enum.GetName(typeof(DriveType), GetDriveType(s))));
      }
    }


  • Opción 2:
    Código (csharp) [Seleccionar]

    using System;
    using System.Management;

    public class ListDrives {
      public static void Main(string[] args) {
        string query = "SELECT * FROM win32_logicaldisk";
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
        foreach(ManagementObject obj in searcher.Get())
          Console.WriteLine("Objeto: " + obj.GetText(TextFormat.Mof)); // Aqui tendrias que filtrar segun DriveType
      }
    }
#83
Si te sirve de ayuda, te puedo decir cómo hacerlo utilizando los comandos de Linux (se pueden usar desde Windows instalando Cygwin):
ls *.jpg | tr '\n' ' ' > salida.txt
Básicamente sería:
1. Mostrar todos los ficheros .jpg del directorio actual (ls *.jpg)
2. Sustituir el salto de línea por un espacio (tr '\n' ' ')
3. Guardar la salida en el fichero salida.txt (> salida.txt)

No sé si habrá algún equivalente al comando tr en Windows.
#84
El problema de que te muestre nan como resultado es porque estás calculando números demasiado grandes. Realizar una serie de Taylor para el sen(x) con una precisión de 360 (como estás calculando tú) es una locura.
Llamando precisión al número de elementos de la serie que se calculan, tenemos lo siguiente:

Elemento 1: denominador = 1! = (1 * 2 - 1)!
Elemento 2: denominador = 3! = (2 * 2 - 1)!
Elemento 3: denominador = 5! = (3 * 2 - 1)!
Elemento 4: denominador = 7! = (4 * 2 - 1)!
...
Elemento 360: denominador = (360 * 2 - 1)! = 719!

Puedes intentar calcular 719! a ver qué pasa...

Una precisión de 10 es más que suficiente para una aproximación decente.
Dicho esto volvamos con el código en sí. La cosa es calcular cada uno de los elementos de la serie correctamente. Empezamos.
La estructura general del programa es la siguiente:
Código (cpp) [Seleccionar]

#include <iostream>
#include <cmath>

using namespace std;

const int PRECISION = 10;

int main() {
  double x = 2; // Un valor cualquiera para calcular sen(x)

  double resultado = 0;
  for(int i = 0; i < PRECISION; ++i) {
    resultado += signo * numerador / denominador;
  }

  cout << "El resultado aproximado de sen(" << x << ") es: " << resultado << endl;
  cout << "El resultado real de sen(" << x << ") es: " << sin(x) << endl;
}

Ahora falta calcular cada una de las variables (signo, numerador, denominador).

Para calcular el signo, como ya te dije, basta con ir multiplicando por -1 en cada iteración.
Código (cpp) [Seleccionar]

//...
int signo = 1; // Empezamos con 1 porque el primer elemento es positivo
for(int i = 0; i < PRECISION; ++i) {
  resultado += signo * numerador / denominador;
  signo *= -1; // Cambiamos el signo a -1 para la siguiente iteracion
}
//...


Ahora para calcular el numerador, como ya dije también, hay que darse cuenta de que en cada iteración está elevado a un exponente 2 veces mayor.

Elemento 1: numerador = x^1 = x ^ (1 * 2 - 1)
Elemento 2: numerador = x^3 = x ^ (2 * 2 - 1)
Elemento 3: numerador = x^5 = x ^ (3 * 2 - 1)
...

La primera opción es calcular:
Código (cpp) [Seleccionar]

for(int i = 0; i < PRECISION; ++i) {
  numerador = pow(x, i * 2 - 1);
  //...
}

Pero esto requiere demasiados cálculos innecesarios. Como ya dije:
Citar
Lo mismo pasa con una potencia: si tienes x y lo multiplicas por x, ya tienes x^2. Si x^2 lo multiplicas por x, ya tienes x^3 y así sucesivamente también.
Entonces la mejor opción es:
Código (cpp) [Seleccionar]

//...
double numerador = x; // El primer numerador es x^1 entonces lo dejamos ya almacenado
for(int i = 0; i < PRECISION; ++i) {
  resultado += signo * numerador / denominador;
  signo *= -1; // Cambiamos el signo a -1 para la siguiente iteracion
  numerador *= (x * x); // Si tenemos x^1 y lo multiplicamos por x^2 (x*x), obtenemos x^3
}
//...


Y ya sólo quedaría el denominador. Vuelvo a mencionar lo que dije en el mensaje anterior:
Citar
Piensa que si en una iteración tienes 1! y lo multiplicas por 2, ya tienes 2!. Si 2! lo multiplicas por 3, ya tienes 3!; y así sucesivamente sin tener que hacer todas las operaciones en cada iteración.
Aquí también podríamos calcular el factorial de (2^n-1) pero volverían a ser un montón de cálculos innecesarios. Vamos a ver cómo funcionan los factoriales otra vez:

Elemento 1: denominador = 1! = (1 * 2 - 1)!
Elemento 2: denominador = 3! = (2 * 2 - 1)! = 1! * 2 * 3
Elemento 3: denominador = 5! = (3 * 2 - 1)! = 3! * 4 * 5
Elemento 4: denominador = 7! = (4 * 2 - 1)! = 5! * 6 * 7
...

Como ves, si en la primera iteración tenemos 1!, luego hay que multiplicar por 2 y por 3 para conseguir 3!. Para conseguir el 5! como ya tenemos 3! sólo hay que multiplicar por 4 y por 5 y así sucesivamente.
Código (cpp) [Seleccionar]

//...
double denominador = 1; // El primer denominador es 1! (1) entonces lo dejamos ya almacenado
for(int i = 0; i < PRECISION; ++i) {
  resultado += signo * numerador / denominador;
  signo *= -1; // Cambiamos el signo a -1 para la siguiente iteracion
  numerador *= (x * x); // Si tenemos x^1 y lo multiplicamos por x^2 (x*x), obtenemos x^3
  denominador *= ((i+2) * 2 - 2) * ((i+2) * 2 - 1);
}
//...

Tenemos que sumar 2 a i porque al empezar en 0, obtendríamos números negativos en las primeras iteraciones. Este valor que se suma a i dependerá del número (i) con el que se empiecen a contar las iteraciones.
#85
Antes que nada: el código debe ir entre etiquetas de Código GeSHi. Puedes seleccionar el código, ir al desplegable de "Código GeSHi" encima del cuadro de texto y elegir el lenguaje correspondiente (C en este caso) o escribir directamente tú las etiquetas en el cuadro de texto de la siguiente manera:
[code=c]
Aquí tu código C
[/code]



Claro que se puede simplificar ese código y además ya tienes comentado por ahí cómo hacerlo: utilizando arrays.
Otro consejo es que utilices constantes en vez de utilizar números sueltos que no se sabe lo que significan. Además si en algún momento quieres cambiar su valor, basta con cambiarlo al declarar la constante y no en todo el código.

// cabeceras

#define NUM_CARACTERES 37 // Constante para el numero de caracteres

int main() {
  char abecedario[] = "abcd..";
  char cifrado[] = "...";
  int estadisticas[NUM_CARACTERES] = {0}; // Inicializamos todo el array a 0
  // Se puede hacer una comprobacion para evitar errores en tiempo de ejecucion mediante <assert.h>
  assert(strlen(abecedario) == strlen(cifrado) && NUM_CARACTERES >= strlen(abecedario)); // Lanza un error si la condicion no es cierta
 
  FILE *fichero_simple = fopen("texto_simple.txt", "r");
  FILE *fichero_cifrado = fopen("texto_cifrado.txt", "wt");
  // Comprobar que los ficheros se han abierto correctamente y en caso contrario, terminar el programa

  char caracterActual;
  int encontrado = 0; // se puede usar bool mediante <stdbool.h>
  while((caracterActual = fgetc(fichero_simple)) != EOF) {
    for(int i = 0; i < strlen(abecedario) && !encontrado; ++i) {
      encontrado = (caracterActual == abecedario[i]);
      if(encontrado) {
        caracter = cifrado[i];
        ++estadisticas[i];
      }
    }
    fputc(caracter, fichero_cifrado); // De esta forma si un caracter no lo encuentra, lo copia sin cifrar
    encontrado = 0;
  }

  // Cerrar ficheros de texto simple y cifrado

  FILE *fichero_estadisticas = fopen("estadisticas.txt", "wt");
  // Comprobar que se ha abierto correctamente
 
  for(int i = 0; i < strlen(abecedario); ++i)
    fprintf(fichero_estadisticas, "%c = %d\n", abecedario[i], estadisticas[i]);

  // Cerrar fichero de estadisticas
}
#86
Python puede llegar a ser tan compacto...
Código (python) [Seleccionar]

palabras = ["casa", "coche", "calle"]
respuesta = input("Escribe una frase con alguna de estas palabras " + str(palabras) + ": ")
valido = any(palabra in respuesta for palabra in palabras)
print("Correcto!!" if valido else "Incorrecto...")
#87
Tu problema se puede resumir en:
Código (csharp) [Seleccionar]

int[] arrayNumeros;
List<int> listaNumeros;
arrayNumeros = listaNumeros; // Error!! Se esta asignando una List<int> a un int[]
arrayNumeros = listaNumeros.ToArray(); // OK
listaNumeros = arrayNumeros; // Error!! Se esta asignando un int[] a una List<int>
listaNumeros = arrayNumeros.ToList(); // OK
#88
Lo primero: avisarte de que he borrado el otro tema que has abierto para el mismo problema.
Lo segundo: es mejor si los títulos de los temas son algo más descriptivos así que he cambiado el título de este tema.


En C++ el operador ^ es un XOR (OR exclusivo) que funciona bit a bit. Para usar potencias hay que utilizar la función pow(). Podrías hacerlo así limitándote a usar la fórmula con potencias y factoriales pero la cantidad de cálculos que va a tener que hacer tu programa va a ser muy grande.

Lo mejor es aprovechar que tu programa es iterativo para ahorrarte operaciones que ya tienes.
Piensa que si en una iteración tienes 1! y lo multiplicas por 2, ya tienes 2!. Si 2! lo multiplicas por 3, ya tienes 3!; y así sucesivamente sin tener que hacer todas las operaciones en cada iteración.
Lo mismo pasa con una potencia: si tienes x y lo multiplicas por x, ya tienes x^2. Si x^2 lo multiplicas por x, ya tienes x^3 y así sucesivamente también.

Ahora tienes que ver cómo ir almacenando estos resultados parciales en cada iteración.
No puedo ser más concreto ahora mismo porque no tengo tiempo.
#89
Programación C/C++ / Re: duda codigo simple C
23 Marzo 2021, 21:52 PM
Tienes que estudiar las posibilidades que existen y lo que debería hacer tu función en cada caso:
  • Caso 1: strlen(cadena1) < strlen(cadena2) -> Copia tantos caracteres como tenga cadena1

    cadena1 = Hola
    cadena2 = Adios
    resultado -> cadena1 = Adio


  • Caso 2: strlen(cadena1) = strlen(cadena2) -> Copia tantos caracteres como tengan ambas

    cadena1 = Hola
    cadena2 = aloH
    resultado -> cadena1 = aloH


  • Caso 3: strlen(cadena1) > strlen(cadena2) -> Copia tantos caracteres como tenga cadena2 y corta la cadena

    cadena1 = Adios
    cadena2 = Hola
    resultado -> cadena1 = Hola -> no cadena1 = Holas


    Al final si sacamos un patrón de todo esto es que se copian tantos caracteres como tenga la cadena más corta de las dos y el siguiente caracter tiene que ser el de fin de cadena '\0'.
    Para los casos 2 y 3 vistos antes bastaría con hacer la modificación que ha comentado @Eternal Idol porque la cadena más corta es cadena2; sin embargo, en el caso 1 nos generará problemas de acceso a memoria.

    Para que funcione en todos los casos es necesario comprobar cuál es la cadena más corta de las dos:

    char *my_strcpy(char *cadena1, char *cadena2) {
      int longitud_minima = strlen(cadena1);
      if(strlen(cadena2) < longitud_minima) longitud_minima = strlen(cadena2);
      for(int i = 0; i <= longitud_minima; ++i) // la ultima iteracion servira para copiar el caracter '\0'
        cadena1[i] = cadena2[i];
      return cadena1;
    }
#90
La verdad es que la explicación es un poco complicada para el que no sepa de qué le están hablando.
Intuyo que la historia empieza por las series de Taylor y su forma de aproximar funciones como el sen(x) mediante una sumatoria.
Para ver la fórmula de la serie de Taylor para sen(x): https://es.wikipedia.org/wiki/Serie_de_Taylor#Funciones_trigonom%C3%A9tricas
La fórmula dice algo así como:
sen(x) = SUM(n=0->inf) ((-1)^n / (2n+1)! * x^(2n+1)) =
       = x^1/1! - x^3/3! + x^5/5! - x^7/7! + x^9/9! - ...

Ahora igual ya sí podemos empezar a hacer algo...

Si te das cuenta tú estás calculando:
sen(x) = 1+x^1/1 + x^2/2 + x^3/4 + x^4/16 + ...
Por lo que parece que ahí fallan más cosas.

De todas formas, cambiar el signo es muy sencillo. Aunque no nos demos cuenta, cuando cambiamos el signo de algo lo estamos multiplicando por -1. Entonces:
Código (cpp) [Seleccionar]

int numero = 5;
for(int i = 0; i < 10; ++i)
  cout << numero << " ";
  numero *= -1; // numero = numero * -1
}

Salida:
5 -5 5 -5 5 -5 5 -5 5 -5