Open beatriz-paz opened 1 year ago
Dia proposto para pesquisar soluções dos problemas encontrados em sala e compartilha-las no próximo encontro.
A struct criada será definida como Acoes.
struct Acoes{
string data;
double preco, preco_crescente, probabilidade_dias;
}
Dentro dela será possível acessar o preço e a data, que agora testamos armazenar dentro de um vetor. A escolha do vetor se deu pois cada local armazenado nele já tem uma ordem crescente, sendo mais fácil de localizar cada informação. Assim, dispensamos o uso da lista, já que não seria preciso trocar os dados de lugar nessa ocasião.
//criando um vetor do tipo Acoes que foi criado
vector<Acoes>info_acoes;
//cria uma variavel linha para conseguir armazenar a linha lida do arquivo no loop
string linha;
//ler as linhas do arquivo, armazenando em um vetor os precos
while (getline(arq, linha)) {
istringstream frase(linha);
Acoes dados_acoes;
frase >> dados_acoes.data >> dados_acoes.preco; // ler a linha do arquivo e armazena a data e o preço na struct criada através do operador de extração ">>"
info_acoes.push_back(dados_acoes); //adiciona ao vetor a struct
}
Depois disso, pensamos em armazenar essas informações em uma pilha.
29 de Março de 2023
Novamente na aula de programação, dedicamos o tempo para pensar na lógica do programa e como iria rodar o loop da pilha.
De início criamos uma pilha dessa forma:
//pilha para armazenar "o dia anterior mais próximo cujo preço de ação seja maior que o dia presente."
stack<double>dias_preco_crescente;
dias_preco_crescente.push(0);
Dentro da pilha seria possível contar os dias de preço crescente que é igual ao tamanho dela, pois antes de empilhar um dado de preço, é necessário saber se esse dado é maior que o preço do topo da pilha, se for, desempilha o do topo e empilha o atual, caso contrário só empilha. Alguns testes desse loop não deram certo, por isso teremos que revisar essa parte e ver onde estamos errando.
Além disso, recebemos ideias do professor de criar mais structs para ir armazenando os resultados de cada parte do projeto:
struct Acoes{
string data;
double preco;
};
struct ResultadoUm{
string data;
int dia_com_aumento_preco;
};
struct ResultadoDois{
string data;
double probabilidade_dias = 0;
};
Mas ainda precisamos revisar e definir a lógica por trás do problema para sermos mais precisos na hora de dar o próximo passo.
Conseguimos desenvolver uma forma de empilhar os dados e fazer com que esse loop que funcione:
//pilha para armazenar "o dia anterior mais próximo cujo preço de ação seja maior que o dia presente."
stack<int>dias_preco_crescente;
dias_preco_crescente.push(0);
//vetor para armazenar o dia calculado e a data referente ao calculo para que possamos armazenar os dados dessa pilha
vector<Resultado>dia;
for (int i = 0; i < info_acoes.size(); ++i) {
dia.push_back(Resultado());
while (!dias_preco_crescente.empty() && info_acoes[dias_preco_crescente.top()].preco <= info_acoes[i].preco) {
dias_preco_crescente.pop();
}
if (dias_preco_crescente.empty()) {
dias_preco_crescente.push(i + 1);
dia[i].dias_preco_aumentou = i + 1;
} else {
dia[i].dias_preco_aumentou = i - dias_preco_crescente.top();
dias_preco_crescente.push(1 - dias_preco_crescente.top());
}
dias_preco_crescente.push(i);
dia[i].data = info_acoes[i].data;
}
Para o final precisamos revisar se não existe outra forma mais eficiente.
Fora isso, falta começar a parte de probabilidade.
Iniciamos a parte de probabilidade com a ideia que precisamos ler todos os dias já contados (que estão guardados na struct Resultado), somar quantas vezes cada número apareceu e dividir pelo total. Assim imprimindo, respectivamente, o dia contado e a probabilidade.
Testamos várias vezes esse laço de contagem e não deu certo:
//vector<Contagem>probabilidade_aumento_preco;
vector<Contagem>probabilidade_aumento_preco;
// loop para calcular as probabilidades de duração de preço ascendente
int contador = 0;
for (int i = 0; i < info_acoes.size(); i++) {
int numero = dia[i].dias_preco_aumentou;
while (i < dia.size()) {
numero = dia[i].dias_preco_aumentou;
int digitoAtual = numero % 10;
if (digitoAtual == dia[i].dias_preco_aumentou) {
contador++;
}
int num = numero /= 10;
i++;
}
}
Portanto, tentei de outro modo mas falta testar, se der certo, basta apenas descobrir a quantidade de números e adicionar a divisão de probabilidade.
//vector<Contagem>probabilidade_aumento_preco;
vector<Contagem>probabilidade_aumento_preco;
//adicionando os dias contados do vetor dia no vetor de prob
for(int i = 0; i < dia.size(); i++) {
probabilidade_aumento_preco[i].dia = dia[i].dias_preco_aumentou;
}
sort(probabilidade_aumento_preco.begin(), probabilidade_aumento_preco.end());
int cont = 1;
for (int j = 1; j < probabilidade_aumento_preco.size(); j++) {
if (probabilidade_aumento_preco[j].dia == probabilidade_aumento_preco[j - 1].dia) {
cont++;
} else {
probabilidade_aumento_preco[j-cont].rep = cont;
cont = 1;
}
}
Essa ideia consiste em organizar o vetor da probabilidade com os dias contados por meio do sort e ver quantas vezes ele se repete através do contador, conseguindo já organizar quais são os números e suas ocorrências para facilitar a conta final da probabilidade.
Ainda pensando no código anterior de probabilidade, tentei complementar, jogando os dados ordenados sem repetição em uma fila:
//cria uma fila para os dias sem repetições
queue<int> ordem_dias;
for (int i = 0; i < probabilidade_aumento_preco.size(); i++) {
// se o primeiro num for diferente do segundo, armazena na lista o segundo
if (probabilidade_aumento_preco[i].dia != probabilidade_aumento_preco[i+1].dia) {
ordem_dias.push(probabilidade_aumento_preco[i].dia);
}
} //finaliza a lista com todos os numeros sem as repetiçoes
//conta a probabilidade e armazena na struct
for (int i = 0; i < ordem_dias.size(); i++) {
probabilidade_aumento_preco[i].probabilidade_dias = probabilidade_aumento_preco[i].rep / ordem_dias.size();
}
Porém, hoje, com várias tentativas, conseguimos finalizar a parte de probabilidade, armazenando os dados importantes para o cálculo também através de um contador. Ficou assim:
//vetor que calcula a probabilidade
vector<Contagem>probabilidade_aumento_preco;
for (int i = 0; i < dia.size(); ++i) {
double contador = 0;
int qtd_dia = dia[i].dias_preco_aumentou;
for (int j = 0; j < dia.size(); ++j) {
if (dia[j].dias_preco_aumentou == qtd_dia){
contador++;
}
}
double probabilidade = contador / dia.size();
probabilidade_aumento_preco.push_back(Contagem());
probabilidade_aumento_preco[i].dia = qtd_dia;
probabilidade_aumento_preco[i].probabilidade_dias = probabilidade;
}
Como a função sort não funcionou do jeito inicial, pesquisamos outras formas de ordenar esse vetor:
// usando a função SORT para ordenar o vetor de probabilidade
sort(probabilidade_aumento_preco.begin(), probabilidade_aumento_preco.end(), [](const Contagem& a, const Contagem& b) {
return a.dia < b.dia;
});
// remover elementos duplicados do vetor usando a função UNIQUE
auto it = unique(probabilidade_aumento_preco.begin(), probabilidade_aumento_preco.end(), [](const Contagem& a, const Contagem& b) {
return a.dia == b.dia;
});
probabilidade_aumento_preco.erase(it, probabilidade_aumento_preco.end());
Por algum motivo não era aceito o sort daquele jeito, mas esse funcionou corretamente.
Então, com os valores dos dias ordenados e a conta da probabilidade, obtivemos todos os resultados possíveis. Assim, fizemos com que os resultados saíssem em dois arquivos:
1 - com a data e a quantidade de dias 2 - com os dias e a probabilidade de cada um.
Como a probabilidade teve o resultado em double, criamos outro laço que percorre o vetor de resultados, transforma os valores de várias casas decimais em valores de 4 casas e escreve no arquivo de resultado.
// ARQUIVOS DE SAÍDA
//criando o arquivo de saida "resultado" que contém o calculo da quantidade de dias que teve o aumento do preço
ofstream arq_dias("resultado.txt");
//valida se deu para abrir o arquivo criado
if (not arq_dias.is_open()) {
cerr << "Algum erro ao abrir o arquivo ..." << endl;
return 0;
}
// Percorre o vetor "dia" e escreve cada elemento no arquivo resultado
for (auto elemento : dia) {
arq_dias << elemento.data << " "<< elemento.dias_preco_aumentou << endl;
}
//criando o arquivo de saida "contagem" que contém o calculo da probabilidade de dias que teve o aumento do preço
ofstream arq_probabilidade("contagem.txt");
//valida se deu para abrir o arquivo criado
if (not arq_probabilidade.is_open()) {
cerr << "Algum erro ao abrir o arquivo ..." << endl;
return 0;
}
// Percorre o vetor "probabilidade_aumento_preco" e escreve cada elemento no arquivo resultado
for (auto elemento : probabilidade_aumento_preco) {
// Arredonda o valor do elemento para 4 casas decimais
elemento.probabilidade_dias = round(elemento.probabilidade_dias * 10000) / 10000;
arq_probabilidade << elemento.dia << " " << fixed << setprecision(4) << elemento.probabilidade_dias << endl;
}
Com o código finalizado e funcionando, acrescentamos possíveis funções para que a main não ficasse tão poluída:
//função que le os dados de entrada e armazena em um vetor do tipo "CotacaoAcoes"
vector<CotacaoAcoes>dados_entrada(ifstream * arq)
// função para calcular os dias com preço ascendente e armazenar em um vetor
vector<Resultado>dias_preco_ascendente(vector<CotacaoAcoes>&info_acoes)
// função para calcular a probabilidade de repetição de preço ascendente e armazenar o resultado em um vetor
vector<Contagem>calculo_probabilidade(vector<Resultado>&dia)
// função para ordenar o vetor de probabilidade e remover os valores repetidos
vector<Contagem>ordena_e_remove_rep(vector<Contagem>&probabilidade_aumento_preco)
Com isso, todos os testes resultaram em arquivos idênticos aos do professor.
De forma inexplicável, o programa que funcionou ontem no windows, não funcionou no linux. Após testes que batiam com o resultado do professor, no linux mostrava um erro correspondente a memória. Conferimos e percebemos que havia um problema na pilha que armazenava os dias, devolvendo alguns valores negativos. Após o erro ser consertado, voltou a rodar e gerar os arquivos, porém com resultados totalmente diferentes.
A solução da função da pilha consertada:
// Função para calcular os dias com preço ascendente e armazenar em um vetor
vector<Resultado>dias_preco_ascendente(vector<CotacaoAcoes>&info_acoes){
vector<Resultado>dia;
//pilha para armazenar "o dia anterior mais próximo cujo preço de ação seja maior que o dia presente."
stack<int>dias_preco_crescente;
dias_preco_crescente.push(0);
for (int i = 0; i < info_acoes.size(); ++i) {
dia.push_back(Resultado());
while (!dias_preco_crescente.empty() && info_acoes[dias_preco_crescente.top()].preco <= info_acoes[i].preco) {
dias_preco_crescente.pop();
}
if (dias_preco_crescente.empty()) {
dias_preco_crescente.push(i + 1);
dia[i].dias_preco_aumentou = i + 1;
} else {
dia[i].dias_preco_aumentou = i - dias_preco_crescente.top();
dias_preco_crescente.push(1 + i - dias_preco_crescente.top());
}
dias_preco_crescente.push(i);
dia[i].data = info_acoes[i].data;
}
return dia;
}
Diário de bordo - 27 de Março de 2023
Durante a aula de programação de segunda-feira foi iniciado um projeto que consiste em analisar preços de ações. O programa é dividido em duas partes: a sequência de dias com valores ascendentes e a probabilidade de cada quantidade de dias com valores ascendentes.
Para que a primeira parte do problema fosse possível ser resolvida, iniciamos o código abrindo o arquivo que contém a data e o preço, respectivamente, em cada linha. Além de pensar no possível erro de sua abertura.
Assim que abrisse, o programa iria ler a primeira linha, localizar o preço e armazenar em uma lista de preços.
Contamos com o arquivo tendo um formato padrão dos valores:
Por isso criamos uma função que, após encontrar o primeiro espaço na linha, criasse uma string a partir dessa posição e a denominasse _precodia.
Finalizando o código dessa forma:
Porém, notamos que a ideia de usar listas para esse caso não seria eficiente, então no próximo teste tentaremos usar structs, criando um novo tipo de dado para armazenar todas as informações necessárias, como o preço e os dias, deixando mais organizado e fácil de desenvolver.
Necessário para finalizar o projeto:
Projeto: Analisador de preços de ações Júlia, Beatriz e Leonardo.