Latitude x Temperatura, Tenenbaum 1.2.2

Olá. Essa aqui é a resolução comentada do exercício 1.2.2 da página 54 do livro Estrutura de dados em C, que transcrevo aqui:

Escreva um programa em C que faça o seguinte: Leia um grupo de leituras de temperatura. Uma leitura consiste em dois números: um inteiro entre -90 e 90, representando a latitude na qual a leitura foi efetuada, e a temperatura observada nessa latitude. Imprima uma tabela consistindo em cada latitude e na temperatura média da latitude. Se não existirem leituras em determinada latitude, imprima “sem dados” em vez de uma média. Em seguida, imprima a temperatura média nos hemisférios Norte e Sul (o Norte consiste em latitudes de 1 a 90 e o Sul em latitudes de -1 a -90). (Essa temperatura média deve ser calculada como a média das médias, não como a média das leituras iniciais.) Determine também o hemisfério mais quente. Ao fazer a determinação, use as temperaturas médias em todas as latitudes de cada hemisfério para os quais existem dados tanto para essa latitude como para a latitude correspondente no outro hemisfério. (Por exemplo, se existirem dados para latitude 57, mas não para latitude -57, então a temperatura média para a latitude 57 deve ser ignorada, ao determinar o hemisfério mais quente.)

Tenenbaum, Langsam e Augesnstein (2013)

Decifrando o exercício:

O autor está pedindo que eu crie um array para relacionar a temperatura média com respectiva latitude, que pode variar de -90 (polo sul) a +90 (polo norte) sendo zero a linha do Equador.

Caso eu tenha a temperatura na latitude 30 e não tenha na latitude -30, devo ignorar esses dois valores na hora de fazer o cálculo da média.

Ao terminar de rodar, o programa deve indicar quem tem a temperatura média mais quente: hemisfério norte ou hemisfério sul.

Um programa simples que vai me dar um trabalhão de pesquisa kkkkk. Vai vendo =P.

O que precisa:

  • Pesquisar qual é a temperatura média por latitude.
  • Calcular a temperatura média do hemisfério Norte.
  • Calcular a temperatura média do hemisfério Sul.
  • Informar qual hemisfério tem a maior temperatura média.

Antes de continuarmos:

Meu caro. Se esse artigo lhe ajudar e de alguma forma der um adianto para ti, vou ficar muito feliz se você clicar nos links de meus anunciantes e dar uma olhada no que eles tem para te oferecer. Grato :-).

O perigo de sair programando sem pensar:

Para entregar esse exercício na facool, é só resolver, entregar e pegar a nota. Se for esse seu caso, já pula para a parte que eu mostro o código, ou vá direto no meu repositório no GitHub. O que vem a seguir é para os Nerds de carteirinha.

Talvez os parágrafos a seguir sejam mais importantes que a resolução do exercício em si. Caso você queira entender como minha cabeça está processando o problema antes de sair programando o algoritmo, seja bem vindo em me acompanhar :-).

Chutar valores ou ir atrás de dados corretos?

O exercício pede que eu insira os dados “de cabeça”. Não faz sentido algum. Não dá para conferir se a resposta está certa. Simples assim, não dá para comprovar se está funcionando corretamente. Inclusive, se estiver algum estatístico lendo essa minha página, vou ficar eternamente grato se puderem contribuir para melhorar essa resposta :-).

Para contornar essa questão, fui atrás de um dataset de temperaturas.

E encontrei um relacionando a temperatura média mensal, de acordo com a latitude.

Na verdade, consegui 12 curvas de temperatura média por latitude, listadas mês a mês, extraídas do site climate research nesse link aqui segundo pesquisado em Anglia (2022) e (FEULNER; RAHMSTORF; LEVERMANN; VOLKWARDT, 2013).

Abaixo, na figura 1, segue o print de duas das 12 curvas de temperatura, referentes aos meses Janeiro e Julho, onde destaco as diferenças de temperatura por conta das estações do ano:

Figura 1: Temperatura x Latitude Janeiro Julho. Autor: Renato de Pierri, baseado em Anglia (2022).

Entendendo o gráfico:

Olhando o gráfico da figura 1, dá para notar claramente que a região do Polo Sul, latitude -87,5º, tem uma temperatura média maior em Janeiro de -25,5ºC quando comparado com a temperatura média da região do Polo Norte, latitude 87,5º, que é de -30,3ºC .

Em Julho a situação se inverte. A região do Polo Sul, latitude -87,5º, registra temperatura média de -56,9ºC enquanto que a região do Polo Norte, latitude 87,5º, fica com uma temperatura média de -0,2ºC , bem mais alta.

Ainda olhando na figura 1, No Polo Sul, latitude -87,5º, em Janeiro, temos uma temperatura média é de -25,5ºC e em Julho ela fica na média de -56,9ºC enquanto que no Polo Norte, na latitude 87,5º, a temperatura média em Janeiro é de -30,3ºC e em Julho, a temperatura média é de -0,2ºC, bem mais alta.

É daí que vamos tirar os dados para fazer o exercício.

Voltando ao exercício:

O exercício quer saber no geral quem é mais quente: Hemisfério Norte ou Hemisfério Sul e para chegar nisso, agora temos os dados necessários mas…

O enunciado não fala nada de entrar dados relativos a cada mês, portanto, consultando a tabela 1 abaixo, só nos interessam as colunas “Latitude” e “Média Anual”.

Com essas duas colunas dá para descobrir qual hemisfério é mais quente, considerando a média anual de cada hemisfério.

Tabela 1: Temperatura X Latitude, Janeiro a Dezembro. Autor Renato de Pierri, baseado em Anglia (2022).

Essa volta toda aconteceu porque não encontrei de mão beijada a “Média Anual”, que foi calculada a partir dos dados pesquisados acima.

Habemus in itinere:

Só de olhar para os números da tabela 1, dá para se ter uma ideia de como será a resposta.

Conforme dito, são necessárias as colunas: “Latitude” e “Média Anual” da tabela 1. Dessas duas colunas, o programa irá calcular a temperatura média nos hemisférios Sul e Norte e apontar qual é o mais quente, lembrando que a “Média Anual” é uma coluna calculada, elaborada pelo autor, a partir dos dados obtidos de Anglia(2022).

Caiu a ficha de que entender o enunciado (ou o requisito) e estabelecer uma estratégia para resolver o problema é a parte mais importante da programação?

Uma vez entendido o escopo do problema, a sua resolução fica relativamente fácil e pode ser realizada empregando a maioria das linguagens de programação.

Isso é estudar algoritmos.

A resolução:

Para simplificar e diminuir os erros de digitação, os dados serão entrados automaticamente, havendo a possibilidade de entrada manual de dados, a ser implementada no futuro.

O código dessa implementação, inclusive com os testes unitários, podem ser baixados diretamente de meu repositório no GitHub, clicando aqui.

O código:

main.c: Este código é a entrada do programa.

O main chama as funções principais “le_dados”, “classifica_dados”, “remove_inconsistencias”, “print_erro” e tem o controle da chamada quando em modo debug, quando chama a função RunAllTests”.

#include <stdio.h>
#include <stdlib.h>
#include "funcoes.h"
#include "Teste_unitario/Teste_Latitude_122.h"


/*

Exercício 1.2.2
Escreva um programa em C que faça o seguinte:  Leia  um  grupo  de  leituras  de
temperatura. Uma leitura consiste em dois números: uminteiro  entre  -90  e  90,
representando a latitude  na  qual a  leitura  foi  efetuada,  e  a  temperatura
observada nessa latitude. Imprima uma tabela consistindo em cada latitude  e  na
temperatura  média  da  latitude.  Se  não  existirem  leituras  em  determinada
latitude, imprima "sem dados" em  vez  de  uma  média.  Em  seguida,  imprima  a
temperatura média nos hemisférios Norte e Sul (o  Norte  consiste  em  latitudes
de 1 a 90 e o Sul em latitudes de -1 a -90). (Essa temperatura  média  deve  ser
calculada como a média das médias, não como a média das leituras iniciais.)
Determine também o hemisfério mais quente.  Ao  fazer  a  determinação,  use  as
temperaturas médias em todas as latitudes  de  cada  hemisfério  para  os  quais
existem dados tanto para essa latitude como para a  latitude  correspondente  no
outro hemisfério. (Por exemplo, se existirem dados  para latitude  57,  mas  não
para latitude -57, então  a  temperatura  média  para a  latitude  57  deve  ser
ignorada, ao determinar o hemisfério mais quente.)

Fonte da latitude x temperatura:
https://crudata.uea.ac.uk/cru/data/temperature/

Base do algoritmo de classificacao de dois arrays:
https://stackoverflow.com/questions/32948281/c-sort-two-arrays-the-same-way

Fonte: Estruturas de Dados Usando C - Tenembaum, pg 54.

Autor da solução: Renato de Pierri
https://bit.ly/3Yj7WxI


*/

int main(){

    double vlat[36]= {[0 ... 35]=99};
    double vtemp[36]={[0 ... 35]=99};
    int controle, erro,result = 0;
    int check = 0;
    size_t tamanho;

    do{
        if(DEBUG == 0){
            check = le_dados(vlat,vtemp);
            if (check == 0){
                tamanho = sizeof(vlat)/sizeof(vlat[0]);
                classifica_dados(vlat,vtemp,tamanho);
                erro = remove_inconsistencias(vlat,vtemp,tamanho);
                if (erro >= 51){
                    printf("\nErro irrecuperavel: %i, digitar "
                           "novamente os dados.\n\n",erro);
                    print_erro(erro);
                }else{
                    print_erro(erro);
                    result = calcula_media(vlat,vtemp,tamanho);
                }
            }
            system("pause");
            system("cls");
        }else{
            printf("Rodando testes\n");
            RunAllTests();
            system("pause");
            system("cls");
        }
    }while(CONTINUO == 1);
    return 0;
}

As flags DEBUG e CONTINUO servem para controlar se o programa irá entrar em modo debug ou se rodará em loop contínuo. Esses parâmetros são definidos no cabeçalho do arquivo funcoes.h.

funcoes.h: Esse arquivo contém as configurações de operação do programa e os protótipos das funções utilizadas na solução, conforme exibido no código abaixo.

#ifndef FUNCOES_H_INCLUDED
#define FUNCOES_H_INCLUDED
#include <stdio.h>

/*
DEBUG:      0 - Operacao normal, 1 - Modo de testes.
CONTINUO:   0 - Roda uma vez,    1 - Modo continuo.
AUTOMATICO  0 - Insere manual    1 - Insere dados automaticamente
*/

#define DEBUG 0
#define CONTINUO 1
#define AUTOMATICO 1

int le_dados(double vlat[], double vtemp[]);
void classifica_dados(double vlat[], double vtemp[], size_t tamanho);
int compare(const void *pp0, const void *pp1);
int remove_inconsistencias(double vlat[], double vtemp[], size_t tamanho);
int calcula_media(double vlat[],double vtemp[],size_t tamanho);
int print_erro(int erro);
#endif // FUNCOES_H_INCLUDED

funcoes.c: Esse arquivo é o coração do sistema. Ele possui a implementação de todas funções definidas no arquivo acima, funcoes.h.

Conforme dito, para facilitar a demonstração, os dados são inseridos automaticamente. O programa prevê uma entrada para implementação da leitura manual dos dados, mas essa parte falta ser implementada. Fica como desafio :-).

A função “classifica_dados”, junto com a função “compare”, fazem um quick sort pela latitude nos arrays latitude e temperatura, ficando o polo norte na parte superior do array e o polo sul na parte inferior do array. A parte central do array, corresponde ao Equador, lembrando que a função “compare” define a configuração do quick sort. A parte do quick sort foi baseada em um post do site Stack Overflow.

Um ponto interessante do arquivo funcoes.c é ressaltar é que a função “remove_inconsistencias” retorna um valor inteiro que é um status de erro indicando:

  • Bits 0 e 1: Número de erros de latitude – Digitou um par de latitude desalinhado.
  • Bits 2 e 3: Número de erros de temperatura. – Esqueceu de digitar e ficou o valor padrão “99”.
  • Bits 4, 5 e 6: Total dos erros.

Ainda no mesmo arquivo, essa informação é decodificada pela função “print_erro” que recebe o status de erro e faz o desmembramento dele, manipulando os bits e apresentando corretamente os erros de latitude, temperatura e o total de erros (erros de digitação).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "funcoes.h"
#include "Teste_unitario/CuTest.h"
#include "Teste_unitario/Teste_Latitude_122.h"

int le_dados(double vlat[], double vtemp[]){

    const char * lat[] = {"-82.5","-87.5","-77.5","-72.5","-67.5","-62.5"     ,
                          "-57.5","-52.5","-47.5","-42.5","-37.5","-32.5"     ,
                          "-27.5","-22.5","-17.5","-12.5","-07.5","-02.5"     ,
                          "  2.5","  7.5"," 12.5"," 17.5"," 22.5"," 27.5"     ,
                          " 32.5"," 37.5"," 42.5"," 47.5"," 52.5"," 57.5"     ,
                          " 62.5"," 67.5"," 72.5"," 77.5"," 82.5"," 87.5"     };
    const char * temp[] ={
             "-038.95"           ,"-46.175"              ,"-34.6583333333333" ,
             "-024.6916666666667","-10.7666666666667"    ," -3.34166666666667",
             "    .925"          ,"  4.325"              ,"  7.85"            ,
             "  11.5416666666667"," 15.0166666666667"    ," 17.7666666666667" ,
             "  20.2416666666667"," 22.2416666666667"    ," 23.7666666666667" ,
             "  24.9083333333333"," 25.7666666666667"    ," 25.975"           ,
             "  26.15"           ," 26.3416666666667"    ," 26.4333333333333" ,
             "  25.6666666666667"," 24.05"               ," 21.2833333333333" ,
             "  17.1"            ," 13.6166666666667"    ," 10.075"           ,
             "  6.15"            ,"  3.125"              ,"  0.5"             ,
             " -4.6"             ," -8.83333333333333"   ,"-12.0833333333333" ,
             "-15.1416666666667" ,"-16.7416666666667"    ,"-17.0666666666667" };
    int controle;
    int check = 0;
    char *ptr;
    int tamanho_lat = (sizeof(lat)/sizeof (const char *));

    if(AUTOMATICO){
        printf("Lendo automaticamente os dados \n");
        for(controle = 0;controle<tamanho_lat;controle++){
            vlat [controle] = strtod(lat [controle],&ptr);
            vtemp[controle] = strtod(temp[controle],&ptr);
        }
    }else{
        printf("Entrada manual de dados nao implementada \n");
        check = 1;
        for(controle = 0;controle<tamanho_lat;controle++){
            vlat [controle] = strtod(lat [controle],&ptr);
            vtemp[controle] = strtod(temp[controle],&ptr);

        }
    }
 return check;
}

void classifica_dados(double vlat[], double vtemp[], size_t tamanho){
    double *inter[tamanho];
    size_t i, j, k;
    double va,  vb;

    /* Salvando os ponteiros que indicam os endereços das variaveis  vlat[] */
    for(i = 0; i < tamanho; i++)
        inter[i] = &vlat[i];
    /* Classificando array de ponteiros */
    qsort(inter, tamanho, sizeof(inter[0]), compare);

    /* Alinhando vlat[] e vtemp[] de acordo com a classificacao de inter*/
    for(i = 0; i < tamanho; i++){
        if(i != inter[i]-vlat){
            va = vlat [i];
            vb = vtemp[i];
            k = i;
            while(i != (j = inter[k]-vlat)){
                vlat[k]  =  vlat[j];
                vtemp[k] = vtemp[j];
                inter[k] = &vlat[k];
                k = j;
            }
            vlat[k] =  va;
            vtemp[k] = vb;
            inter[k] = &vlat[k];
        }
    }

    for(i = 0; i < tamanho; i++){
        printf(" %+05.1lf\t%+05.1lf\n", vlat[i], vtemp[i]);
    }
return;
}

int compare(const void *pp0, const void *pp1){
    double i0 = **(double **)pp0;
    double i1 = **(double **)pp1;
    if(i0 > i1)return -1;
    if(i0 < i1)return  1;
    return 0;
}

int remove_inconsistencias(double vlat[], double vtemp[], size_t tamanho){
    int controle;
    int sobe, desce, erro, erro_total;
    erro  =0;
    sobe  = ((int)tamanho/2)-1;
    desce = sobe + 1;
    for (controle = sobe;controle>=0;controle--){
        if((vtemp[sobe]==99)|(vtemp[desce]==99)){
            printf("Inconsistencia na temperatura: %+05.1lf %+05.1lf e "
                   "%+05.1lf %+05.1lf\n",
                   vlat[sobe],vtemp[sobe],vlat[desce],vtemp[desce]);
            erro = erro  +  4;
            erro = erro  + 16;
            vtemp[sobe]  = 99;
            vtemp[desce] = 99;
        }
        if(vlat[sobe]+vlat[desce]!=0){
            erro = erro +  1;
            erro = erro + 16;
            printf("Desalinhamento entre latitude: %+05.1lf %+05.1lf e "
                   "%+05.1lf %+05.1lf\n",
                   vlat[sobe],vtemp[sobe],vlat[desce],vtemp[desce]);
            vtemp[sobe]  = 99;
            vtemp[desce] = 99;
        }
        erro_total = erro >>4;
            if(erro_total >=3){
            printf("\nerro irrecuperavel: %i \n",erro);
                break;
        }
        sobe--;
        desce++;
    }
    printf("\n");
return erro;
}

int calcula_media(double vlat[],double vtemp[],size_t tamanho){
    int controle, sobe, desce,check, elementos = 0;
    double media_total, media_hemisferio_norte, media_hemisferio_sul;
    media_total=0;
    media_hemisferio_norte=0;
    media_hemisferio_sul=0;
    sobe  = ((int)tamanho/2)-1;
    desce = sobe + 1;
    for (controle = sobe;controle>=0;controle--){
        if(vtemp[sobe]!=99){
            media_hemisferio_norte = media_hemisferio_norte +   vtemp[sobe];
            media_hemisferio_sul   = media_hemisferio_sul   +  vtemp[desce];
            media_total = media_total + vtemp[sobe] + vtemp[desce];
            elementos++;
        }
        sobe --;
        desce++;
    }

    media_hemisferio_sul   = media_hemisferio_sul/elementos;
    media_hemisferio_norte = media_hemisferio_norte/elementos;
    media_total            = media_total/(elementos*2);

    printf("Media geral\t\t: %+05.1lf.\n", media_total                     );
    printf("Media hemisferio Norte\t: %+05.1lf.\n", media_hemisferio_norte );
    printf("Media hemisferio Sul\t: %+05.1lf.\n\n", media_hemisferio_sul   );

    if(media_hemisferio_sul > media_hemisferio_norte){
       printf("O hemisferio Sul   tem uma temperatura media maior\n");
       printf("O hemisferio Norte tem uma temperatura media menor\n");
    }else{
        if(media_hemisferio_sul == media_hemisferio_norte){
            printf("A média nos hemisferios Sul e Norte sao iguais" );
        }else{
            printf("O hemisferio Norte\t:tem uma temperatura media maior.\n");
            printf("O hemisferio Sul  \t:tem uma temperatura media menor.\n\n");
        }
    }
    check=(int)((media_hemisferio_sul+media_hemisferio_norte+media_total)*1000);

return check;
}

int print_erro(int erro){
    //Decodifica e imprime o detalhe do erro
    int erro_vlat, erro_vtemp, erro_total = 0;
    int check;
    erro_vlat =   erro  & 3;
    erro_vtemp = (erro >> 2)&3;
    erro_total =  erro >> 4;
    printf("Erros na latitude\t: %i.\n",   erro_vlat   );
    printf("Erros na temperatura\t: %i.\n",erro_vtemp  );
    printf("Total de erros\t\t: %i.\n\n",    erro_total);
    check = erro_vlat+erro_vtemp+erro_total;
return check;
}

Teste_Latitude_122.h e Teste_Latitude_122.c: Esses dois arquivos por sua vez implementam a suíte de testes unitários CuTest.

Teste_Latitude_122.h:

#ifndef TESTE_LATITUDE_122_H_INCLUDED
#define TESTE_LATITUDE_122_H_INCLUDED
#include "../funcoes.h"
#include "CuTest.h"
CuSuite*StrUtilGetSuite();
void RunAllTests(void);
void Teste_Le_Dados_automatico(CuTest *tc);
void Teste_Le_Dados_manual(CuTest *tc);
void Teste_Classifica_Dados(CuTest *tc);
void Teste_Remove_Inconsistencias1(CuTest *tc);
void Teste_Remove_Inconsistencias2(CuTest *tc);
void Teste_Remove_Inconsistencias3(CuTest *tc);
void Teste_Remove_Inconsistencias4(CuTest *tc);
void Teste_Remove_Inconsistencias5(CuTest *tc);
void Teste_Remove_Inconsistencias6(CuTest *tc);
void Teste_Remove_Inconsistencias7(CuTest *tc);
void Teste_Calcula_Media1(CuTest *tc);
void Teste_print_erro1(CuTest *tc);

#endif // TESTE_LATITUDE_122_H_INCLUDED

Teste_Latitude_122.c:

#include "Teste_Latitude_122.h"
#include "../funcoes.h"CuSuite* StrUtilGetSuite();
#include <string.h>

void RunAllTests(void){
    CuString* output = CuStringNew();
    CuSuite* suite = CuSuiteNew();
    CuSuiteAddSuite(suite, StrUtilGetSuite());
    CuSuiteRun(suite);
    CuSuiteSummary(suite, output);
    CuSuiteDetails(suite, output);
    printf ("%s\n\n", output->buffer);
}

void Teste_Le_Dados_automatico(CuTest *tc){
    double vlat[36]= {[0 ... 35]=99};
    double vtemp[36]={[0 ... 35]=99};
    char resp[4]={"ok"};
    CuString* str = CuStringNew();
    le_dados(vlat,vtemp);
    int controle;
    for (controle = 0;controle<=35;controle++){
    if(((vlat[controle]==99)|(vtemp[controle]==99))==1){
        strcpy(resp,"nao");
        break;
        }
    }

    CuStringAppend(str,"ok");
    CuAssertStrEquals(tc,resp , str->buffer);

}

void Teste_Le_Dados_manual(CuTest *tc){
    //Para testar aqui, AUTOMATICO deve ser = 0 em funcoes.h;
    double vlat[36]= {[0 ... 35]=99};
    double vtemp[36]={[0 ... 35]=99};
    char resp[4]={"ok"};
    CuString* str = CuStringNew();
    le_dados(vlat,vtemp);
    int controle;
    for (controle = 0;controle<=35;controle++){
    if(((vlat[controle]==99)|(vtemp[controle]==99))==1){
        strcpy(resp,"nao");
        break;
        }
    }
    CuStringAppend(str,"ok");
    CuAssertStrEquals(tc,resp , str->buffer);
}

void Teste_Classifica_Dados(CuTest *tc){
    double vlat[36]= {[0 ... 35]=99};
    double vtemp[36]={[0 ... 35]=99};
    double prova=0;
    char resp[12];
    CuString* str = CuStringNew();
    le_dados(vlat,vtemp);
    classifica_dados(vlat,vtemp,36);
    prova = vlat[34]+vtemp[34]+vlat[35]+vtemp[35];
    sprintf(resp, "%f", prova);
    CuStringAppend(str,"-255.125000");
    CuAssertStrEquals(tc,resp , str->buffer);
}

void Teste_Remove_Inconsistencias1(CuTest *tc){
    double vlat[36]= {-87.5,-82.5,-77.5,-72.5,-67.5,-62.5,-57.5,-52.5,-47.5,
                      -42.5,-37.5,-32.5,-27.5,-22.5,-17.5,-12.5, -7.5, -2.5,
                        2.5,  7.5, 12.5, 17.5, 22.5, 27.5, 32.5, 37.5, 42.5,
                       47.5, 52.5, 57.5, 62.5, 67.5, 72.5, 77.5, 82.5, 87.5};
    double vtemp[36]={-46.17500000000  ,-38.95000000000  ,-34.65833333333  ,
                      -24.69166666667  ,-10.76666666667  , -3.34166666667  ,
                        0.92500000000  ,  4.32500000000  ,  7.85000000000  ,
                       11.54166666667  , 15.01666666667  , 17.76666666667  ,
                       20.24166666667  , 22.24,66666667  , 23.76666666667  ,
                       24.90833333333  , 25.76666666667  , 25.97500000000  ,
                       26.15000000000  , 26.34166666667  , 26.43333333333  ,
                       25.66666666667  , 24.05000000000  , 21.28333333333  ,
                       17.10000000000  , 13.61666666667  , 10.07500000000  ,
                        6.15000000000  ,  3.12500000000  ,  0.50000000000  ,
                       -4.60000000000  , -8.83333333333  , 12.08333333333  ,
                      -15.14166666667  ,-16.74166666667  ,-17.06666666667  };
    int prova=22;
    char resp[12];
    CuString* str = CuStringNew();
    classifica_dados(vlat,vtemp,36);
    prova = remove_inconsistencias( vlat,  vtemp, 36);
    sprintf(resp, "%i", prova);
    CuStringAppend(str,"0");
    CuAssertStrEquals(tc,resp , str->buffer);
}

void Teste_Remove_Inconsistencias2(CuTest *tc){
    double vlat[36]= {-87.0,-82.5,-77.5,-72.5,-67.5,-62.5,-57.5,-52.5,-47.5,
                      -42.5,-37.5,-32.5,-27.5,-22.5,-17.5,-12.5, -7.5, -2.5,
                        2.5,  7.5, 12.5, 17.5, 22.5, 27.5, 32.5, 37.5, 42.5,
                       47.5, 52.5, 57.5, 62.5, 67.5, 72.5, 77.5, 82.5, 87.5};
    double vtemp[36]={-46.17500000000  ,-38.95000000000  ,-34.65833333333  ,
                      -24.69166666667  ,-10.76666666667  , -3.34166666667  ,
                        0.92500000000  ,  4.32500000000  ,  7.85000000000  ,
                       11.54166666667  , 15.01666666667  , 17.76666666667  ,
                       20.24166666667  , 22.24,66666667  , 23.76666666667  ,
                       24.90833333333  , 25.76666666667  , 25.97500000000  ,
                       26.15000000000  , 26.34166666667  , 26.43333333333  ,
                       25.66666666667  , 24.05000000000  , 21.28333333333  ,
                       17.10000000000  , 13.61666666667  , 10.07500000000  ,
                        6.15000000000  ,  3.12500000000  ,  0.50000000000  ,
                       -4.60000000000  , -8.83333333333  , 12.08333333333  ,
                      -15.14166666667  ,-16.74166666667  ,-17.06666666667  };
    int prova=22;
    char resp[12];
    CuString* str = CuStringNew();
    classifica_dados(vlat,vtemp,36);
    prova = remove_inconsistencias( vlat,  vtemp, 36);
    sprintf(resp, "%i", prova);
    CuStringAppend(str,"17");
    CuAssertStrEquals(tc,resp , str->buffer);
}

void Teste_Remove_Inconsistencias3(CuTest *tc){
    double vlat[36]= {-87.0,-82.5,-77.5,-72.5,-67.5,-62.5,-57.5,-52.5,-47.5,
                      -42.5,-37.5,-32.5,-27.5,-22.5,-17.5,-12.5, -7.5, -2.5,
                        2.5,  7.5, 12.5, 17.5, 22.5, 27.5, 32.5, 37.5, 42.5,
                       47.5, 52.5, 57.5, 62.5, 67.5, 72.5, 77.5, 82.5, 87.5};
    double vtemp[36]={ 99              ,-38.95000000000  ,-34.65833333333  ,
                      -24.69166666667  ,-10.76666666667  , -3.34166666667  ,
                        0.92500000000  ,  4.32500000000  ,  7.85000000000  ,
                       11.54166666667  , 15.01666666667  , 17.76666666667  ,
                       20.24166666667  , 22.24,66666667  , 23.76666666667  ,
                       24.90833333333  , 25.76666666667  , 25.97500000000  ,
                       26.15000000000  , 26.34166666667  , 26.43333333333  ,
                       25.66666666667  , 24.05000000000  , 21.28333333333  ,
                       17.10000000000  , 13.61666666667  , 10.07500000000  ,
                        6.15000000000  ,  3.12500000000  ,  0.50000000000  ,
                       -4.60000000000  , -8.83333333333  , 12.08333333333  ,
                      -15.14166666667  ,-16.74166666667  ,-17.06666666667  };
    int prova=22;
    char resp[12];
    CuString* str = CuStringNew();
    classifica_dados(vlat,vtemp,36);
    prova = remove_inconsistencias( vlat,  vtemp, 36);
    sprintf(resp, "%i", prova);
    CuStringAppend(str,"37");
    CuAssertStrEquals(tc,resp , str->buffer);
}

void Teste_Remove_Inconsistencias4(CuTest *tc){
    double vlat[36]= {-87.0,-82.0,-77.0,-72.5,-67.5,-62.5,-57.5,-52.5,-47.5,
                      -42.5,-37.5,-32.5,-27.5,-22.5,-17.5,-12.5, -7.5, -2.5,
                        2.5,  7.5, 12.5, 17.5, 22.5, 27.5, 32.5, 37.5, 42.5,
                       47.5, 52.5, 57.5, 62.5, 67.5, 72.5, 77.5, 82.5, 87.5};
    double vtemp[36]={-46.17500000000  ,-38.95000000000  ,-34.65833333333  ,
                      -24.69166666667  ,-10.76666666667  , -3.34166666667  ,
                        0.92500000000  ,  4.32500000000  ,  7.85000000000  ,
                       11.54166666667  , 15.01666666667  , 17.76666666667  ,
                       20.24166666667  , 22.24,66666667  , 23.76666666667  ,
                       24.90833333333  , 25.76666666667  , 25.97500000000  ,
                       26.15000000000  , 26.34166666667  , 26.43333333333  ,
                       25.66666666667  , 24.05000000000  , 21.28333333333  ,
                       17.10000000000  , 13.61666666667  , 10.07500000000  ,
                        6.15000000000  ,  3.12500000000  ,  0.50000000000  ,
                       -4.60000000000  , -8.83333333333  , 12.08333333333  ,
                      -15.14166666667  ,-16.74166666667  ,-17.06666666667  };
    int prova=22;
    char resp[12];
    CuString* str = CuStringNew();
    classifica_dados(vlat,vtemp,36);
    prova = remove_inconsistencias( vlat,  vtemp, 36);
    sprintf(resp, "%i", prova);
    CuStringAppend(str,"51");
    CuAssertStrEquals(tc,resp , str->buffer);
}

void Teste_Remove_Inconsistencias5(CuTest *tc){
    double vlat[36]= {-87.5,-82.5,-77.5,-72.5,-67.5,-62.5,-57.5,-52.5,-47.5,
                      -42.5,-37.5,-32.5,-27.5,-22.5,-17.5,-12.5, -7.5, -2.5,
                        2.5,  7.5, 12.5, 17.5, 22.5, 27.5, 32.5, 37.5, 42.5,
                       47.5, 52.5, 57.5, 62.5, 67.5, 72.5, 77.5, 82.5, 87.5};
    double vtemp[36]={ 99              , 99              ,-34.65833333333  ,
                      -24.69166666667  ,-10.76666666667  , -3.34166666667  ,
                        0.92500000000  ,  4.32500000000  ,  7.85000000000  ,
                       11.54166666667  , 15.01666666667  , 17.76666666667  ,
                       20.24166666667  , 22.24,66666667  , 23.76666666667  ,
                       24.90833333333  , 25.76666666667  , 25.97500000000  ,
                       26.15000000000  , 26.34166666667  , 26.43333333333  ,
                       25.66666666667  , 24.05000000000  , 21.28333333333  ,
                       17.10000000000  , 13.61666666667  , 10.07500000000  ,
                        6.15000000000  ,  3.12500000000  ,  0.50000000000  ,
                       -4.60000000000  , -8.83333333333  , 12.08333333333  ,
                      -15.14166666667  ,-16.74166666667  ,-17.06666666667  };
    int prova=22;
    char resp[12];
    CuString* str = CuStringNew();
    classifica_dados(vlat,vtemp,36);
    prova = remove_inconsistencias( vlat,  vtemp, 36);
    sprintf(resp, "%i", prova);
    CuStringAppend(str,"40");
    CuAssertStrEquals(tc,resp , str->buffer);
}

void Teste_Remove_Inconsistencias6(CuTest *tc){
    double vlat[36]= {-87.5,-82.5,-77.5,-72.5,-67.5,-62.5,-57.5,-52.5,-47.5,
                      -42.5,-37.5,-32.5,-27.5,-22.5,-17.5,-12.5, -7.5, -2.5,
                        2.5,  7.5, 12.5, 17.5, 22.5, 27.5, 32.5, 37.5, 42.5,
                       47.5, 52.5, 57.5, 62.5, 67.5, 72.5, 77.5, 82.5, 87.5};
    double vtemp[36]={ 99              , 99              , 99              ,
                      -24.69166666667  ,-10.76666666667  , -3.34166666667  ,
                        0.92500000000  ,  4.32500000000  ,  7.85000000000  ,
                       11.54166666667  , 15.01666666667  , 17.76666666667  ,
                       20.24166666667  , 22.24,66666667  , 23.76666666667  ,
                       24.90833333333  , 25.76666666667  , 25.97500000000  ,
                       26.15000000000  , 26.34166666667  , 26.43333333333  ,
                       25.66666666667  , 24.05000000000  , 21.28333333333  ,
                       17.10000000000  , 13.61666666667  , 10.07500000000  ,
                        6.15000000000  ,  3.12500000000  ,  0.50000000000  ,
                       -4.60000000000  , -8.83333333333  , 12.08333333333  ,
                      -15.14166666667  ,-16.74166666667  ,-17.06666666667  };
    int prova=22;
    char resp[12];
    CuString* str = CuStringNew();
    classifica_dados(vlat,vtemp,36);
    prova = remove_inconsistencias( vlat,  vtemp, 36);
    sprintf(resp, "%i", prova);
    CuStringAppend(str,"60");
    CuAssertStrEquals(tc,resp , str->buffer);
}

void Teste_Remove_Inconsistencias7(CuTest *tc){
    double vlat[36]= {-87.0,-82.0,-77.0,-72.5,-67.5,-62.5,-57.5,-52.5,-47.5,
                      -42.5,-37.5,-32.5,-27.5,-22.5,-17.5,-12.5, -7.5, -2.5,
                        2.5,  7.5, 12.5, 17.5, 22.5, 27.5, 32.5, 37.5, 42.5,
                       47.5, 52.5, 57.5, 62.5, 67.5, 72.5, 77.5, 82.5, 87.5};
    double vtemp[36]={ 99              , 99              , 99              ,
                      -24.69166666667  ,-10.76666666667  , -3.34166666667  ,
                        0.92500000000  ,  4.32500000000  ,  7.85000000000  ,
                       11.54166666667  , 15.01666666667  , 17.76666666667  ,
                       20.24166666667  , 22.24,66666667  , 23.76666666667  ,
                       24.90833333333  , 25.76666666667  , 25.97500000000  ,
                       26.15000000000  , 26.34166666667  , 26.43333333333  ,
                       25.66666666667  , 24.05000000000  , 21.28333333333  ,
                       17.10000000000  , 13.61666666667  , 10.07500000000  ,
                        6.15000000000  ,  3.12500000000  ,  0.50000000000  ,
                       -4.60000000000  , -8.83333333333  , 12.08333333333  ,
                      -15.14166666667  ,-16.74166666667  ,-17.06666666667  };
    int prova=22;
    char resp[12];
    CuString* str = CuStringNew();
    classifica_dados(vlat,vtemp,36);
    prova = remove_inconsistencias( vlat,  vtemp, 36);
    sprintf(resp, "%i", prova);
    CuStringAppend(str,"74");
    CuAssertStrEquals(tc,resp , str->buffer);
}

void Teste_Calcula_Media1(CuTest *tc){
    double vlat[36]= { 87.5, 82.5, 77.5, 72.5, 67.5, 62.5, 57.5, 52.5, 47.5,
                       42.5, 37.5, 32.5, 27.5, 22.5, 17.5, 12.5,  7.5,  2.5,
                       -2.5, -7.5,-12.5,-17.5,-22.5,-27.5,-32.5,-37.5,-42.5,
                      -47.5,-52.5,-57.5,-62.5,-67.5,-72.5,-77.5,-82.5,-87.5};
    double vtemp[36]={-17.06666666667  ,-16.74166666667  ,-15.14166666667  ,
                      -12.08333333333  , -8.83333333333  , -4.60000000000  ,
                        0.50000000000  ,  3.12500000000  ,  6.15000000000  ,
                       10.07500000000  , 13.61666666667  , 17.10000000000  ,
                       21.28333333333  , 24.05000000000  , 25.66666666667  ,
                       26.43333333333  , 26.34166666667  , 26.15000000000  ,
                       25.97500000000  , 25.76666666667  , 24.90833333333  ,
                       23.76666666667  , 22.24166666667  , 20.24166666667  ,
                       17.76666666667  , 15.01666666667  , 11.54166666667  ,
                        7.85000000000  ,  4.32500000000  ,  0.92500000000  ,
                       -3.34166666667  ,-10.76666666667  ,-24.69166666667  ,
                      -34.65833333333  ,-38.95000000000  ,-46.17500000000  };
    int prova=22;
    char resp[12];
    CuString* str = CuStringNew();
    prova = calcula_media(vlat,vtemp,36);
    sprintf(resp, "%i", prova);
    CuStringAppend(str,"13980");
    CuAssertStrEquals(tc,resp , str->buffer);
}

void Teste_print_erro1(CuTest *tc){
    CuString* str = CuStringNew();
    int prova;
    char resp[12];
    prova = print_erro(111);
    sprintf(resp, "%i", prova);
    CuStringAppend(str,"12");
    system("cls");
    CuAssertStrEquals(tc,resp , str->buffer);
}

CuSuite*StrUtilGetSuite(){
    CuSuite* suite = CuSuiteNew();

    SUITE_ADD_TEST(suite,Teste_Le_Dados_automatico);
    SUITE_ADD_TEST(suite,Teste_Le_Dados_manual);
    SUITE_ADD_TEST(suite, Teste_Classifica_Dados);
    SUITE_ADD_TEST(suite,Teste_Remove_Inconsistencias1);
    SUITE_ADD_TEST(suite,Teste_Remove_Inconsistencias2);
    SUITE_ADD_TEST(suite,Teste_Remove_Inconsistencias3);
    SUITE_ADD_TEST(suite,Teste_Remove_Inconsistencias4);
    SUITE_ADD_TEST(suite,Teste_Remove_Inconsistencias5);
    SUITE_ADD_TEST(suite,Teste_Remove_Inconsistencias6);
    SUITE_ADD_TEST(suite,Teste_Remove_Inconsistencias7);
    SUITE_ADD_TEST(suite,Teste_Calcula_Media1);
    SUITE_ADD_TEST(suite,Teste_print_erro1);
}

O código dessa implementação, inclusive com os testes unitários, podem ser baixados diretamente de meu repositório no GitHub, clicando aqui.

No GitHub, na pasta arquivos adicionais, estão disponíveis arquivos complementares como a tabela 1 no formato Excel e também no formato original, “absolute_v5.nc” que pode ser aberto com o programa R ou com o programa Panoply.

Essa solução utiliza a biblioteca de teste unitário CuTest que é de código aberto e pode ser baixada diretamente no site do SourceForge, clicando aqui.

Como a solução está documentada com os testes unitários, é possível apagar a solução empregada, rodar os testes unitários (vai dar um monte de erro) e implementar o código no seu estilo, resolvendo cada um dos erros do teste unitário até as coisas funcionarem e de quebra, podendo dar uma olhadinha em como eu montei a resposta… ou não :-D.

Como sempre, muito obrigado e não esqueça de clicar nos anúncios e ver o que os anunciantes tem de bom para te oferecer.

Bons estudos!

Bibliografia:

ANGLIA, University Of East. Climate Reserach Unit: data. Data. 2022. Disponível em: https://crudata.uea.ac.uk/cru/data/temperature/#sciref. Acesso em: 25 jan. 2023.

FEULNER, Georg; RAHMSTORF, Stefan; LEVERMANN, Anders; VOLKWARDT, Silvia. On the Origin of the Surface Air Temperature Difference between the Hemispheres in Earth’s Present-Day Climate. Journal Of Climate. Potsdam, Brandenburg, Germany, p. 7136-7150. set. 2013. Disponível em: https://bit.ly/3WBYlAT. Acesso em: 25 jan. 2023.

OVERFLOW, Stack (comp.). C – Sort two arrays the same way. 2016. Disponível em: https://stackoverflow.com/questions/32948281/c-sort-two-arrays-the-same-way. Acesso em: 01 fev. 2023.

TENENBAUM, Aaron M.; LANGSAM, Yedidyah; AUGESNSTEIN, Moshe J.. Estruturas de Dados Usando C. São Paulo: Pearson, 2013. 884 p. ISBN 13: 978-85-346-0348-5, pg 53 – 54.

Last updated by at .