Jump to content

Programa que não altera a variável contador (uso isalpha)


Recommended Posts

Posted (edited)

Olá programadores 🙂 ,

neste programa algo esta acontecer de errado, já fiz debug no eclipse mas não percebi muito bem . vi que a string/frase está a ser passada e a solução está idêntica a apresentada no livro(verifiquei alterações e isso, não resolveu).

obrigado pelas opiniões!!

como podem ver:

Q5AvX8i.png

#include "stdio.h"
#include "ctype.h" // vamos utilizar estas Funções que já demos !!
int strcount(char s[])
{
//char ch; // dado ser fornecida uma string eu vou mas é verificar se o index  da string corresponde ou não ..
int i,contador;

   for (i = contador = 0; s[i] != '\0'; i++);
   {
       if ( isalpha(s[i]))
           contador++;//ch = getchar(); dá forma que estava a pensar se não fosse passada por parâmetro
   }
   printf( " A frase:\" %s tem %d carateres alfabéticos\"\n",s,contador);
   return contador;
}

int main()
{
   strcount("Ontem fui comprar um electrodoméstico");
   return 0;
}
Edited by jonhhy
Posted (edited)

Olá programadores 🙂 ,

neste programa algo esta acontecer de errado, já fiz debug no eclipse mas não percebi muito bem . vi que a string/frase está a ser passada e a solução está idêntica a apresentada no livro(verifiquei alterações e isso, não resolveu).

obrigado pelas opiniões!!

como podem ver:

Q5AvX8i.png

#include "stdio.h"
#include "ctype.h" // vamos utilizar estas Funções que já demos !!
int strcount(char s[])
{
//char ch; // dado ser fornecida uma string eu vou mas é verificar se o index  da string corresponde ou não ..
int i,contador;

   for (i = contador = 0; s[i] != '\0'; i++);
   {
       if ( isalpha(s[i]))
           contador++;//ch = getchar(); dá forma que estava a pensar se não fosse passada por parâmetro
   }
   printf( " A frase:\" %s tem %d carateres alfabéticos\"\n",s,contador);
   return contador;
}

int main()
{
   strcount("Ontem fui comprar um electrodoméstico");
   return 0;
}

Faz lá debug outra vez e vê qual o valor do i no if.

depois tira o ";" que tens a seguir ao for, e vê a diferença

Edited by Flinger
  • Vote 1
Posted (edited)

Já agora aproveito para realçar mais um detalhe!

A função int strcount(char s[]); retorna um valor inteiro. Então, faria todo o sentido usar o retorno da função na função que a chama, ou seja, usar o retorno da função int strcount(char s[]); na função main, ou então alterar o protótipo da função de forma a não retornar qualquer valor!

Versão 1 com retorno do valor "contador"

#include "stdio.h"
#include "ctype.h" // vamos utilizar estas Funções que já demos !!
int strcount(char s[])
{
//char ch; // dado ser fornecida uma string eu vou mas é verificar se o index  da string corresponde ou não ..
int i, contador = 0;

   for (i = 0; s[i] != '\0'; i++)
   {
       if ( isalpha(s[i]))
           contador++;//ch = getchar(); dá forma que estava a pensar se não fosse passada por parâmetro
   }   
   return contador;
}

int main()
{
   printf( " A frase:\" %s tem %d carateres alfabéticos\"\n", "Ontem fui comprar um electrodoméstico", strcount("Ontem fui comprar um electrodoméstico"));
   return 0;
}

Versão 2 sem retorno do valor "contador"

#include "stdio.h"
#include "ctype.h" // vamos utilizar estas Funções que já demos !!
void strcount(char s[])
{
//char ch; // dado ser fornecida uma string eu vou mas é verificar se o index  da string corresponde ou não ..
int i, contador = 0;

   for (i = 0; s[i] != '\0'; i++)
   {
       if ( isalpha(s[i]))
           contador++;//ch = getchar(); dá forma que estava a pensar se não fosse passada por parâmetro
   }
   printf( " A frase:\" %s tem %d carateres alfabéticos\"\n",s,contador);
}

int main()
{
   strcount("Ontem fui comprar um electrodoméstico");
   return 0;
}
Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

Pegando no aspecto importante referido pelo PsySc0rpi0n, podemos (e devemos!) levar esse código a nível ainda superior.

O PsySc0rpi0n disse (e muito bem) que se não pretendes utilizar o resultado de uma função, então não precisas que ela devolva nada. No entanto, neste caso, parece-me que o mais natural é que a função devolva um número que possas utilizar noutros locais.

Portanto, se o objectivo é ter uma função que conta o número de caracteres alfabéticos numa string, então essa função deverá fazer apenas e só isso. No teu código a função faz bem mais que isso: além de contar os caracteres, escreve também para o output do programa (e é isto que está a mais).

Fica então a sugestão:

/* o nome stralphacount é mais apropriado que strcount */
int stralphacount(char *str) {
   int i, n = 0;
   for (i = 0; str[i] != '\0'; ++i)
       if (isalpha(str[i]))
           n += 1;
   return n;
}

Depois, podes facilmente utilizar a função stralphacount():

int main(void) {
   char *frase = "Ontem fui comprar um electrodoméstico";
   printf("A frase \"%s\" tem %d caracteres alfabéticos\n", frase, stralphacount(frase));

   return 0;
}

Assim consegues uma separação adequada da lógica e apresentação, que é algo importante desde muito cedo.

  • Vote 1
  • 2 weeks later...
Posted

Mto obrigado pelas respostas (é muito bom ver outras formas de fazer a mesma coisa , por malta que já passou por isto e consegue facilmente identificar este tipo de coisas, pois expande o nosso raciocínio ( a estruturação e lógica das mesmas). Que vai ser muito útil quando pegarmos em pedaços de código maiores em projetos de equipa etc 👍

no mesmo seguimento surgiu-me um dúvida (no exercício a seguir):

da-me segmentation fault! (imagem)

neste programa,

#include "stdio.h"
#include "ctype.h"
char *init_str(char *s)
{

printf ("Frase Original: \" %s \"",s);
s[0] = '\0';
printf( " A frase final:\" %s \"\n",s);
return s;
}

int main()
{
init_str("Ontem fui comprar um electrodoméstico");
return 0;
}

pego numa string de C (logo char * como parâmetro) e retorno outra string em C logo o mesmo char * , só que esta é uma string vazia??.

Nc9IgY6.png é mais ou menos isto que está na solução,

p.s(ainda não cheguei à parte do malloc)

Posted

jonhhy,

O problema ocorre quando tentas modificar a string que foi passada, por um motivo simples: a tua string foi alocada num local de memória só-de-leitura, e qualquer tentativa de alterar resulta num comportamento indefinido, que no caso do teu compilador é uma violação de acesso (segfault).

Para que funcione, terás que declarar a string antes de a utilizares, assim:

char str[] = "Ontem fui comprar um electrodoméstico";
  • 1 month later...
Posted

olá tenho outra dúvida que é: com os  segmentation fault são erros que me tem acontecido frequentemente e ainda não percebi ao que se deve

#define DIM 3
#define ESPACO ' '

void inic(char s[] [DIM])  // Omitir uma dimensão
{
	int i,j;
	for (i=0;i<DIM;i++)
		for (j=0;j<DIM;i++)
			s[i][j]=ESPACO;
}

void mostra(char s[DIM][DIM]) // Ambas as Dimensões
{
	int i,j;
	for (i=0; i<DIM; i++)
	{
		for(j=0;j<DIM;j++)
			printf("%c %c",s[i] [j], j==DIM -1? ' ': '|');
		if (i!=DIM-1) printf("\n-----------");
		putchar('\n');
	}
}


//verifica(){for ()}

int main()
{
	char Velha[DIM][DIM]=0;
	mostra(Velha);
	int posx, posy;
	char ch = '0'; // Caractere para Jogar
	int n_jogadas = 0;

	inic(Velha);
	while (1) // Laço infinito
	{
		mostra(Velha);
		printf("\n Introduza a Posição de Jogo Linha Coluna: ");
		scanf("%d %d", &posx,&posy);
		posx--;posy--; // Eles querem fazer uma atribuição  , um decremento xD ..? Pois os índices do vetor começam em 0
		if (Velha[posx][posy]==ESPACO) // Casa livre
		{ Velha[posx][posy]= ch = (ch == '0') ? 'X' : '0';
		  n_jogadas++;
		}
		else
			printf("Posição já ocupada\nJogue Novamente!!!\n");
		if (n_jogadas == DIM*DIM)
			break; // Acabar o Programa
	}
	mostra(Velha);
	
}

 

#define DIM 3
#define ESPACO ' '

// Por motivos de clareza de código o autor decidiu fazer a declaração das funções apesar de não ser necessário..

void inic(char s[][DIM]);
void mostra (char s[DIM][DIM]);
int Ganhou(char g[DIM][DIM], char ch);
int Linha(char v[], char c);
int Coluna (char g[DIM][DIM], int col, char ch);


// Inicia o Tabuleiro 
void inic(char s[] [DIM])  // Omitir uma dimensão
{
	int i,j;
	for (i=0;i<DIM;i++)
		for (j=0;j<DIM;i++)
			s[i][j]=ESPACO;
}

// Mostra o aspecto do tabuleiro
void mostra(char s[DIM][DIM]) // Ambas as Dimensões
{
	int i,j;
	for (i=0; i<DIM; i++)
	{
		for(j=0;j<DIM;j++)
			printf("%c %c",s[i] [j], j==DIM -1? ' ': '|');
		if (i!=DIM-1) printf("\n-----------");
		putchar('\n');
	}
}

//verifica(){for ()}

int main()
{
	char Velha[DIM][DIM];
	int posx, posy;
	char ch = '0'; // Caractere para Jogar
	int n_jogadas = 0;

	inic(Velha);
	while (1) // Laço infinito
	{
		mostra(Velha);
		printf("\n Introduza a Posição de Jogo Linha Coluna: ");
		scanf("%d %d", &posx,&posy);
		posx--;posy--; // Eles querem fazer uma atribuição  , um decremento xD ..? Pois os índices do vetor começam em 0
		if (Velha[posx][posy]==ESPACO) // Casa livre
		{ Velha[posx][posy]= ch = (ch == '0') ? 'X' : '0';
		  n_jogadas++;
		}
		else
			printf("Posição já ocupada\nJogue Novamente!!!\n");
		if (n_jogadas == DIM*DIM)
			break; // Acabar o Programa
	}
	mostra(Velha);
}


p.s: os códigos partem do mesmo devia só ter um

Posted (edited)

Sem olhar muito atentamente para o código, na função void inic(char s[] [DIM]) // Omitir uma dimensão  do primeiro bloco de código, é intencional incrementar a mesma variável nos dois for's???

 

E colocaste aqui 2 blocos de código porquê? São duas sugestões diferentes? Ainda não percebi!

 

Edited:

Eu não sabia que se podia passer uma matriz para uma função, omitindo o número de linhas mas depois vi isto e ajudou a esclarecer:

http://c-faq.com/aryptr/pass2dary.html

Edited by PsySc0rpi0n
  • Vote 2

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted
39 minutes ago, Flinger said:

Tá aqui qualquer coisa a moer...

Oh @HappyHippyHippo, percebes mais destes formalismos que eu,


 char Velha[DIM][DIM]=0;

 

Isto não põe o apontador a NULL?

pior que isso, essa inicialização é inválida em C

não é possível inicializar um array através de um valor numérico, quanto muito, teria de ser:

char vec[DIM][DIM] = {0};

isto sim é válido, inicializando toda a memória reservada a zero

IRC : sim, é algo que ainda existe >> #p@p
Posted
xpto@xpto-K52Jc:~/Documents/ip$ gcc -W GaloDamasC6E04.c -o Galo
GaloDamasC6E04.c: In function ‘main’:
GaloDamasC6E04.c:78:30: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
   if (posx> DIM || posy> DIM);
                              ^
xpto@xpto-K52Jc:~/Documents/ip$ ./Galo
Segmentation fault (core dumped)

// esquecer: Os erros: ETYT7EY.png

o código:

#include "stdio.h"
#include "ctype.h"
#define DIM 3
#define ESPACO ' '

// Por motivos de clareza de código o autor decidiu fazer a declaração das funções apesar de não ser necessário..

void inic(char s[][DIM]);
void mostra (char s[DIM][DIM]);
int Ganhou(char g[DIM][DIM], char ch);
int Linha(char v[], char c);
int Coluna (char g[DIM][DIM], int col, char ch);


// Inicia o Tabuleiro 
void inic(char s[] [DIM])  // Omitir uma dimensão
{
	int i,j;
	for (i=0;i<DIM;i++)
		for (j=0;j<DIM;i++)
			s[i][j]=ESPACO;
}

// Mostra o aspecto do tabuleiro
void mostra(char s[DIM][DIM]) // Ambas as Dimensões
{
	int i,j;
	for (i=0; i<DIM; i++)
	{
		for(j=0;j<DIM;j++)
			printf("%c %c",s[i] [j], j==DIM -1? ' ': '|');
		if (i!=DIM-1) printf("\n-----------");
		putchar('\n');
	}
}

//verifica(){for ()} Verifica se a n-ésima linha está preenchida com o char c
int Linha(char Ln[], char c) // este int é de Verd ou Falso binário é um bool
	{
	return Ln[0]==Ln[1] && Ln[1]==Ln[2] && Ln[0]==c;
	}
// Verifica se a coluna col está toda preenchida com o char ch
int Coluna (char v[DIM][DIM],int col, char ch)
	{
		return v[0][col] == v[1][col] && v[1][col] == v[2][col] && v[0][col] == ch;
	}

int Diagonal (char v[DIM][DIM], char ch)
	{
		return v[0][0] == v[1][1] && v[1][1] == v[2][2] && v[2][2] == ch || v[2][0] == v[1][1] && v[2][0] == v[0][2] && v[0][2] == ch; 
	}
	
int Ganhou( char M[DIM][DIM], char ch)
	{
		//return Diagonal(M[DIM][DIM],ch) || Coluna( ... esquece com os if's detecto as codinções em que se verificam Afirmaço ou Falsidades e aí sim detetam passa a verdadi !!
 	// e usar um ou - exclusivo!??!
 	if ( Linha(M[0],ch || Linha(M[1],ch) || Linha(M[2],ch)) ) // se linha 1 ou 2 ou 3 tiverem totalmente preenchida com o carater do jogador 
		return 1;//Ganha(1)
	if ( Coluna(M,0,ch) || Coluna(M,1,ch) || Coluna(M,2,ch) )
		return 1;
	if ( Diagonal(M, ch))
		return 1;
	return 0; // Não ganhou
	}
int main()
{
	char Velha[DIM][DIM];
	int posx, posy;
	char ch = '0'; // Caractere para Jogar
	int n_jogadas = 0;

	inic(Velha);
	while (1) // Laço infinito
	{
		mostra(Velha);
		printf("\n Introduza a Posição de Jogo Linha Coluna: ");
		scanf("%d %d", &posx,&posy);
		if (posx> DIM || posy> DIM);
			printf("\n\n****Valores Inválidos****\n\n");
		continue; // Próxima iteração
		posx--;posy--; // Eles querem fazer uma atribuição  , um decremento xD ..? Pois os índices do vetor começam em 0
		if (Velha[posx][posy]==ESPACO) // Casa livre
		{ 
		  Velha[posx][posy]= ch = (ch == '0') ? 'X' : '0';
		  n_jogadas++;
		
			if (Ganhou(Velha,ch)) /* Basta verificar o jogador corrente */
				{
				printf("\n\n**** Ganhou o Jogador %c ****\n\n", ch);
				break;
				}
		}
	else
			printf("Posição já ocupada\nJogue Novamente!!!\n");
		if (n_jogadas == DIM*DIM)
		{
			printf("\n\n**** EMPATE TÉCNICO ****\n\n");
			break; // Acabar o Programa
		}
	}
	mostra(Velha);
	return 0;
}

 

Atualizado, não estou com o livro agora mas ainda vou confirma (fiquei com dúvidas nas versões diferentes que tenho e  o porque dá o segmentation fault e as diferenças que tenho na inicialização da matriz)

//vou editar melhor e ver os erros peço desculpa,


//o outro código que postei era o que era dado para completar o exercício do livros Linguagem C do Luis Damas Cáp. 6 exercício proposto 4

Posted

@jonhhy,

Num fórum de programação espera-se que coloques os erros que obtiveste num bloco de código e não numa imagem. Imagina que alguém encontra o mesmo erro que tu; se tivesses colocado os erros em texto, essa pessoa poderá encontrar este tópico com a função de pesquisa, mas como colocaste numa imagem, não só a pessoa não encontra o tópico e irá criar um duplicado, como também dificultas imenso quem te quer ajudar.

Altera o teu post de modo a corrigir isso.

Posted (edited)

okay já descobri o erro no código, obrigado pela ajuda na mesma!  👍

na matriz estava a incrementar nos 2 ciclos fora a mesma variável (i) e daí o segmentation fault

 

// Inicia o Tabuleiro 
void inic(char s[] [DIM])  // Omitir uma dimensão
{
	int i,j;
	for (i=0;i<DIM;i++)
		for (j=0;j<DIM;i++) //ERRADO! 	é j++
			s[i][j]=ESPACO
Edited by jonhhy
Posted
6 hours ago, jonhhy said:

okay já descobri o erro no código, obrigado pela ajuda na mesma!  👍

na matriz estava a incrementar nos 2 ciclos fora a mesma variável (i) e daí o segmentation fault

 


// Inicia o Tabuleiro 
void inic(char s[] [DIM])  // Omitir uma dimensão
{
	int i,j;
	for (i=0;i<DIM;i++)
		for (j=0;j<DIM;i++) //ERRADO! 	é j++
			s[i][j]=ESPACO

Eu já tinha dito que devias ter isso aí mal, mas parece que não ligaste nenhuma a esse meu post! :|

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted
Em 16/09/2016 às 23:12, PsySc0rpi0n disse:

Eu já tinha dito que devias ter isso aí mal, mas parece que não ligaste nenhuma a esse meu post! 😐

Sim tens toda a razão, peço desculpa PsySc0rpi0n e

entretanto já corrigi as chavetas no código e um ; depois de um if (apaguei) e este funciona:

#include "stdio.h"

#define DIM 3
#define ESPACO ' '

// Por motivos de clareza de código o autor decidiu fazer a declaração das funções apesar de não ser necessário..
// pois vem antes da função principal do main!
void inic (char s[][DIM]);
void mostra (char s[DIM][DIM]);
int Ganhou (char g[DIM][DIM], char ch);
int Linha (char v[], char c);
int Coluna (char g[DIM][DIM], int col, char ch);

// Inicia o Tabuleiro
void
inic (char s[][DIM])		// Omitir uma dimensão
{
  int i, j;
  for (i = 0; i < DIM; i++)
    for (j = 0; j < DIM; j++)
      s[i][j] = ESPACO;
}

// Mostra o aspecto do tabuleiro
void
mostra (char s[DIM][DIM])	// Ambas as Dimensões
{
  int i, j;
  for (i = 0; i < DIM; i++)
    {
      for (j = 0; j < DIM; j++)
	printf ("%c %c", s[i][j], j == DIM - 1 ? ' ' : '|');
      if (i != DIM - 1)
	printf ("\n-----------");
      putchar ('\n');
    }
}

//verifica(){for ()} Verifica se a n-ésima linha está preenchida com o char c
int
Linha (char Ln[], char c)	// este int é de Verd ou Falso binário é um bool
{
  return Ln[0] == Ln[1] && Ln[1] == Ln[2] && Ln[0] == c;
}

// Verifica se a coluna col está toda preenchida com o char ch
int
Coluna (char v[DIM][DIM], int col, char ch)
{
  return v[0][col] == v[1][col] && v[1][col] == v[2][col] && v[0][col] == ch;
}

int
Diagonal (char v[DIM][DIM], char ch)
{
  return ( (v[0][0] == v[1][1])  && (v[1][1] == v[2][2]) && v[2][2] == ch)
    || (v[2][0] == v[1][1] && v[2][0] == v[0][2] && v[0][2] == ch);
}

int
Ganhou (char M[DIM][DIM], char ch)
{
  //return Diagonal(M[DIM][DIM],ch) || Coluna( ... esquece com os if's detecto as codinções em que se verificam Afirmaço ou Falsidades e aí sim detetam passa a verdadi !!
  // e usar um ou - exclusivo!??!
  if (Linha (M[0], ch || Linha (M[1], ch) || Linha (M[2], ch)))	// se linha 1 ou 2 ou 3 tiverem totalmente preenchida com o carater do jogador
    return 1;			//Ganha(1)
  if (Coluna (M, 0, ch) || Coluna (M, 1, ch) || Coluna (M, 2, ch))
    return 1;
  if (Diagonal (M, ch))
    return 1;
  return 0;			// Não ganhou
}

int
main ()
{
  char Velha[DIM][DIM];
  int posx, posy;
  char ch = '0';		// Caractere para Jogar
  int n_jogadas = 0;

  inic (Velha);
  while (1)			// Laço infinito
    {
      mostra (Velha);
      printf ("\n Introduza a Posição de Jogo Linha Coluna: ");
      scanf ("%d %d", &posx, &posy);
      if (posx > DIM || posy > DIM)
      {
	printf ("\n\n****Valores Inválidos****\n\n");
	continue;		// Próxima iteração
      }
      posx--;
      posy--;			// Eles querem fazer uma atribuição  , um decremento xD ..? Pois os índices do vetor começam em 0
      if (Velha[posx][posy] == ESPACO)	// Casa livre
	{
	  Velha[posx][posy] = ch = (ch == '0') ? 'X' : '0';
	  n_jogadas++;

	  if (Ganhou (Velha, ch))	/* Basta verificar o jogador corrente */

	    {
	      printf ("\n\n**** Ganhou o Jogador %c ****\n\n", ch);
	      break;
	    }
	}
      else
	printf ("Posição já ocupada\nJogue Novamente!!!\n");
      if (n_jogadas == DIM * DIM)
	{
	  printf ("\n\n**** EMPATE TÉCNICO ****\n\n");
	  break;		// Acabar o Programa
	}
    }
  mostra (Velha);
  return 0;
}


Apesar disto ele não deteta que ganha .. 😕 e devia acontecer , por isso vou ver melhor a função Ganhou se encontrar alguma coisa edito aqui

xpto@xpto-K52Jc:~/Documents/ip$ gcc -W GaloDamasC6E04.c -o Galo
xpto@xpto-K52Jc:~/Documents/ip$ ./Galo
  |  |   
-----------
  |  |   
-----------
  |  |   

 Introduza a Posição de Jogo Linha Coluna: 2 1
  |  |   
-----------
X |  |   
-----------
  |  |   

 Introduza a Posição de Jogo Linha Coluna: 3 1
  |  |   
-----------
X |  |   
-----------
0 |  |   

 Introduza a Posição de Jogo Linha Coluna: 2 2
  |  |   
-----------
X |X |   
-----------
0 |  |   

 Introduza a Posição de Jogo Linha Coluna: 1 2
  |0 |   
-----------
X |X |   
-----------
0 |  |   

 Introduza a Posição de Jogo Linha Coluna: 2 3
  |0 |   
-----------
X |X |X  
-----------
0 |  |   

 Introduza a Posição de Jogo Linha Coluna: 3 
3
  |0 |   
-----------
X |X |X  
-----------
0 |  |0  

 Introduza a Posição de Jogo Linha Coluna: 1 3
  |0 |X  
-----------
X |X |X  
-----------
0 |  |0  

 Introduza a Posição de Jogo Linha Coluna: 3 2
  |0 |X  
-----------
X |X |X  
-----------
0 |0 |0  

 Introduza a Posição de Jogo Linha Coluna: 1 1


**** EMPATE TÉCNICO ****

X |0 |X  
-----------
X |X |X  
-----------
0 |0 |0  

 edit: e obrigado pelos links ajudaram 😉

  • 4 weeks later...
Posted
if (Linha (M[0], ch || Linha (M[1], ch) || Linha (M[2], ch)))	// se linha 1 ou 2 ou 3 tiverem totalmente preenchida com o carater do jogador
    return 1;			//Ganha(1)

//Bug aqui ,corrigido em baixo

if (Linha (M[0], ch) || Linha (M[1], ch) || Linha (M[2], ch))
    return 1;	

Resolvido!

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.