Feda /dev/ - No Javascript allowed

Normas
spoiler
Personas non gratas
Memes feda dev




desu

madre mia los fperos haciendo videos sin tener ni puta idea AHHAHAHA

minuto 7:08 explica los cons de este approach...

a ver quien me lo sabe resolver sin usar otro metodo que "recomienda xq es mejor y no tiene el cons" HAHAHAH

pista, con varnish no se arregla

1 respuesta
RubberDuck

Estoy haciendo un ejercicio en el que metí un "return false;" como condición else dentro de un bucle, que hacía que el programa pudiese arrojar un valor false antes de tiempo.

Código incorrecto:

spoiler

Código correcto:

spoiler

Pero lo que más me rayó fue que el mensaje de error que me daba era:
non-void function does not return a value in all control paths

¿Son cosas mías o el mensaje de error es impreciso? Es decir, la función siempre devolvía un valor true o false, aunque pudiese devolver un valor false antes de comprobar todos los elementos del array. ¿No es confuso el mensaje de error? Me rompí la cabeza un buen rato intentando ver en qué condición no devolvía true o false, hasta que le pregunté al asistente de IA que tiene edx y me explicó que era que podía terminarse el bucle antes de tiempo con un valor false...

La conversación de besugos con el asistente, para el que se quiera reír:

spoiler
3 respuestas
Konishi

#59522 creo que el problema que te está dando es porque no hay return si el bucle nunca empieza por no cumplirse la condición inicial. Y luego tienes otro posible fallo relacionado.

Edit: no había visto lo de la conversación con el bot. Cuidado con tomarte todo lo que dice en serio. Está bien para cosas de detalles técnicos, pero para la lógica de lo que haces puede desvariar muchísimo

1 respuesta
RubberDuck

#59523 Estoy leyendo el código con lo que me has dicho, a ver si me aclaro. Ahora te digo algo, gracias.

Edit: tal como yo lo veo, el bucle siempre se ejecuta (aunque solo realice la primera iteración, no las demás), y empieza comparando el nombre proporcionado por el usuario con el primer elemento del array. Si coincide, arroja true. Si no, false. El problema es que, en caso de que el nombre proporcionado por el usuario no coincidiera con el primer elemento del array, tendría que seguir comprobando los demás elementos del array, y no devolver false y dar por terminado el bucle.

desu

#59522 tienes el return false mal. debes devolver despues del bucle for, lo que ahora estas haciendo es comprovar solo el primero, si lo he han votado true, sino false. y tu quieres buscar si le han votado o no.

non-void function does not return a value in all control paths

obvio, si la lista es vacia, candidate_count = 0, nunca entra en el bucle for y como ademas has puesto el return false mal, no devuelve nada tu funcion

bool vote(string name) {
    for (int i = 0; i < candidate_count; i++) {
        if (strcmp(name, candidates[i].name) == 0) {
            candidates[i].votes++;
            printf("Candidate %s has now %i votes\n", candidates[i].name, candidates[i].votes);
            return true;
        }
    }
    return false;
}
1 1 respuesta
laZAr0

#59522 Tú código no entra siempre en el bucle for, y más allá del bucle for, no hay nada. Lo que puedes hacer es evaluar la condición del bucle fuera, con un if para saber si candidate_count está vacío por ejemplo, o poner directamente un return fuera del bucle for, en el cuerpo de la función vote, antes de la última llave de cierre.

1 respuesta
PiradoIV

#59521 Ah, esa es fácil: Xojo

https://documentation.xojo.com/api/ios/iosmobiletabledatasourcereordering.html

RubberDuck
#59525desu:

tienes el return false mal. debes devolver despues del bucle for, lo que ahora estas haciendo es comprovar solo el primero, si lo he han votado true, sino false. y tu quieres buscar si le han votado o no.

Sí, eso es lo que dije en:

#59524RubberDuck:

tal como yo lo veo, el bucle siempre se ejecuta (aunque solo realice la primera iteración, no las demás), y empieza comparando el nombre proporcionado por el usuario con el primer elemento del array. Si coincide, arroja true. Si no, false.

Con respecto a:

#59526laZAr0:

Tú código no entra siempre en el bucle for

#59525desu:

obvio, si la lista es vacia, candidate_count = 0, nunca entra en el bucle for

Esto es culpa mía por no haber puesto el código completo, ya que había unas líneas al principio que forzaban al usuario a introducir al menos un candidato.

// Check for invalid usage
    if (argc < 2)
    {
        printf("Usage: plurality [candidate ...]\n");
        return 1;
    }

// Populate array of candidates
candidate_count = argc - 1;

Esto hace que el usuario tenga que poner al menos un nombre, lo que fuerza a su vez que candidate_count sea como mínimo 1.

Pego todo el código aquí (aunque aún tengo que formular la segunda función (print_winner).

spoiler

En resumen, que mi duda solo era que si el bucle sí que se ejecutaba al menos la primera iteración (y arrojaba true en caso de que el usuario introdujera el nombre del primer candidato y false en cualquier otro caso), el mensaje de error no debería ser que "non-void function does not return a value in all control paths", porque sí que devuelve sí o sí true o false en la primera iteración y sale del bucle.
Todo este rollo era solo porque esa frase de error me confundió y me hizo buscar un buen rato donde no era. Debería haberme dicho algo diferente, como "return false inside loop might cause exit before checking every array item" o algo similar. Sí, ya sé que es pedir mucho, pero es que la otra frase (si no me equivoco) es imprecisa y no se cumple, ya que la función sí que devuelve un valor.

1 respuesta
laZAr0

#59528 da igual que el flujo de tu código obligue a que la lista de candidatos no esté vacía, eso la función vote no lo sabe ni tiene por qué saberlo, lo sabes tú que estás haciendo el código para un caso de uso concreto. La función no sabe que tú no vas a hacer otra llamada en cualquier otra parte o momento. Podrías pasar como parámetro la lista de candidatos y evaluar que no fuese nula o este vacía dentro de la función.

1 respuesta
RubberDuck

#59529

#59529laZAr0:

da igual que el flujo de tu código obligue a que la lista de candidatos no esté vacía, eso la función vote no lo sabe ni tiene por qué saberlo

OK, gracias, lo tengo en cuenta (joder, qué perdido estoy). La lista de candidatos se crea al ejecutar el programa, en la propia línea de comandos (./plurality Trump Perrosanxe), y la variable candidate_count está declarada de forma global ¿Aún así la función vote no lo tiene claro?

2 respuestas
desu

#59530 No tiene nada que ver con que el compilador lo tenga claro, la función esta mal escrita.

El compilador no sabe si quieres devolver false o es que el programador es imbecil y ha escrito mal el codigo, como es tu caso que has puesto el return false dentro del for loop.

Porque debería saber el compilador que esa funcion tiene que devolver false y no devolver true?

el usage no se entiende, hay un standard y una guia de estilo para las CLI, usalos o dile a chatgpt que te lo genere.

Usage: plurality [candidate ...]

deberia ser:

Usage: plurality candidate [candidate...]

xq minimo 1 obligatrio

1 1 respuesta
laZAr0

#59530 tú hazle caso a desu que sabe más. Yo soy un fpero como tú, aunque con algo más de recorrido, pero a nivel técnico tampoco tengo los conocimientos para explicarte las cosas con el rigor con el que se han de explicar.

Dicho lo cual, piensa que una función es una cajita aislada que siempre hace una misma tarea, le llega algo y siempre hace lo mismo con ese algo. Para que esté bien escrita siempre debe de responder de la misma manera, que en tu caso es devolviendo un booleano, y según la tienes escrita, hay un caso en el que el flujo de ejecución lleva a un punto en el que no hay retorno. Eso es lo que te dice el mensaje de error.

Además, en tu caso, depende del valor de una variable global que ni si quiera está controlada en el ámbito de esa función, y ese valor podría verse cambiado en cualquier momento dando efectivamente al caso que no tienes controlado.

1 1 respuesta
RubberDuck

#59532 #59531 Anotado, gracias.

1 respuesta
laZAr0

#59533 nada. En cualquier caso te recomiendo que las dudas las preguntes en el otro hilo, la plataforma de juniors, porque este hilo es una taberna off topic y aunque hoy has tenido suerte te podrían haber ignorado o respondido cualquier animalada. xd

1
desu
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#define MAX_CANDIDATES 9

struct candidate {
    string name;
    uint8_t votes;
};

bool vote(const size_t candidates_len, struct candidate candidates[], const string name);
void print_winner(const size_t candidates_len, const struct candidate candidates[]);

int main(const int argc, const string argv[]) {
    if (argc < 2) {
        printf("Usage: plurality candidate [candidate ...]\n");
        return EXIT_FAILURE;
    }

if (argc > MAX_CANDIDATES + 1) {
    printf("Maximum number of candidates is %i\n", MAX_CANDIDATES);
    return EXIT_FAILURE;
}

const size_t number_of_candidates = argc - 1;
struct candidate candidates[number_of_candidates];
for (size_t i = 0; i < number_of_candidates; i++) {
    candidates[i].name = argv[i + 1];
    candidates[i].votes = 0;


    for (size_t j = 0; j < i; j++) {
        if (strcmp(candidates[i].name, candidates[j].name) == 0) {
            printf("Error: Duplicate candidate name '%s'\n", candidates[i].name);
            return EXIT_FAILURE;
        }
    }
}

const int number_of_votes = get_int("Number of voters: ");
if (number_of_votes < 1) {
    printf("Invalid number of voters\n");
    return EXIT_FAILURE;
}

for (size_t i = 0; i < number_of_votes; i++) {
    const string name = get_string("Vote to candidate: ");

    if (!vote(number_of_candidates, candidates, name)) {
        printf("Invalid vote.\n");
        return EXIT_FAILURE;
    }
}

print_winner(number_of_candidates, candidates);
return EXIT_SUCCESS;
}

bool vote(const size_t candidates_len, struct candidate candidates[], const string name) {
    for (size_t i = 0; i < candidates_len; i++) {
        if (strcmp(name, candidates[i].name) == 0) {
            candidates[i].votes++;
            return true;
        }
    }
    return false;
}

void print_winner(const size_t candidates_len, const struct candidate candidates[]) {
    uint8_t max_votes = 0;

for (size_t i = 0; i < candidates_len; i++) {
    if (candidates[i].votes > max_votes) {
        max_votes = candidates[i].votes;
    }
}

printf("Winner(s):\n");
for (size_t i = 0; i < candidates_len; i++) {
    if (candidates[i].votes == max_votes) {
        printf("%s with %i votes\n", candidates[i].name, candidates[i].votes);
    }
}
}

  • candidates inicializado a MAX en lugar de number_of_candidates, mal
// Array of candidates
candidate candidates[MAX];

// Number of candidates
int candidate_count;
  • ambas variables globales en lugar de locales
  • el return 1 y return 2? xq no siempre return 1??? mejor usar la variable de alias
  • candidatos repetidos
  • el caso de empate estoy seguro q te lo habrias dejado, mal también
  • los loops no se hacen sobre int, se hacen sobre size_t porque asi puedes ejecutarse en cualqueir arquitectura 32bit o 64bit o XXXbit
  • me faltan consts

mejor:

struct {
  string name;
  int votes;
} candidate;

VS

typedef struct
{
    string name;
    int votes;
} candidate;
  • los votos siempre son positivos, no hace falta usar int que acepta negativos, mejor usar unsigned int, uint8, uint16 etc

Nota final: 2/10 suspendido

Edit: Nota final: 1/10, que seguro que te dejarias pasar la len del array por parametros.

1 respuesta
Kaledros

Pregunta de examen de observabilidad, quiero conocer opiniones.

Tenéis tres servicios, A, B y C. A es la puerta de entrada que recibe peticiones http del exterior y llama a B. B llama a C, que hace sus cosas y devuelve el resultado a B, que lo devuelve a A para que lo tire hacia afuera. Ahora imaginad que algo peta en C. ¿Cuál de los siguientes approaches elegís?

  • Que sólo C loguee el error. B y A sólo tienen que tratar la respuesta con error sin loguearla y devolver error al usuario. La política es que sólo el servicio donde salta el error debe loguearlo.
  • Que C loguee el error, B también al recibirlo de C y A también al recibirlo de B. La política es que cualquier servicio que reciba un error debe loguearlo aunque le venga de otro sistema.
2 respuestas
wdaoajw

#59536

Loguean el error todos. No necesariamente van a loguear el mismo error. C sacará el stacktrace del error mientras que A igual simplemente loguean que C le ha tirado un 500.

Piensa que es posible que A no conecte solo con C, si no con más servicios

Metes algún sistema de tracing (Zipkin, tempo, etc) y te hace el trabajo solito con su graph de servicios incluidos

3 2 respuestas
RubberDuck

#59535
Como programador:10/10
Como profesor: 1/10

Y ya te expliqué por qué no debías ponerte a hacer tochos que a mí no me iban a aportar nada porque aún no he llegado ahí. Me iba a poner a subrayar todas las partes de ese código que aún nadie me ha explicado por lo menos para que entiendas dónde te estás pasando de frenada, pero no tengo tiempo ahora mismo...

1 respuesta
desu

#59537 el tracing distribuido es una mala practica
#59538 ahi esta el meme, q nada de lo q te digo te sirve HAHAHAHAHAAHAHAHAHHAHAHAH es como si Einstein da una clase de fiisca en pre-escolar

1 respuesta
Lolth

RubberDuck
#59539desu:

ahi esta el meme, q nada de lo q te digo te sirve HAHAHAHAHAAHAHAHAHHAHAHAH es como si Einstein da una clase de fiisca en pre-escolar

El tema es que un buen profesor sabe adaptarse y explicar en función de la pregunta que le hagan y del nivel que tenga el que necesita la respuesta, no se pone a dejar el código perfecto con conceptos de 3er año. Que después te extrañas de que no te aceptaran de profesor en Carnegie, y quizás es que es eso lo que te falló, que vas a demostrar tus máximas capacidades como programador y no como educador. Probablemente necesitasen una persona que mostrase el equilibrio óptimo entre ambas aptitudes. Como ya te dije, no se puede ser bueno en todo.

1 respuesta
HeXaN
#59541RubberDuck:

Probablemente necesitasen una persona

Sin más.

1 1 respuesta
RubberDuck

#59542 Los primeros días llegué a pensar "algún día me dirán que es un bot al que le han puesto de prompt que demuestre máximos conocimientos y soberbia con mínima explicación", y la verdad es que me quedaría con cara de "tiene todo el sentido". Cuesta creer que una persona sea así 24/7 sin que le dé un poquito de vergüenza.

1 respuesta
Soltrac

#59543 nometerseconlosasperger.jpg

desu

Mi nivel de profesor es Feynman.

Dudar de ello solo es negar la realidad.

Ahora, te quiero enseñar?

Obvio que no.

1 respuesta
Kaledros
#59537wdaoajw:

Loguean el error todos

Yo lo que veo es que así lo que obtienes son tres alertas de error que te hacen perder el tiempo hasta encontrar el problema real. De hecho, hasta averiguar que las tres representan el mismo problema.

1 respuesta
RubberDuck
#59545desu:

Mi nivel de profesor es Feynman.

You mean:

Dr_Manhattan

me hace gracia ver a los nuevos con la ilusión en la cara cada vez que desu se interesa por ellos simplemente para ponerse por encima y luego acaban dándose de golpe con la realidad jajajaj.

Veo todo esto con mi banjo desde el porchado de mi casa decadente en luisiana

desu

2
wdaoajw

#59546 ???? Porque? Metes el traceID en cualquiera de estas herramientas y vas a ver el error clarisimo.

Vas a ver la traza completa como finalmente retorna un 500, pero en los spans veras como se resuelven las llamadas y cual es el servicio que esta lanzando el error. Incluso depende como este montado el sistema, podrás incluso ver los logs directamente

1 respuesta