Old procedure guy

Hello, community.

I am trying to convert myself from old procedures and shells programming to Julia.
I am strugling to learn objects and the Julia paradigm but a lot of old habits come across.
So, I developed a program to create a graphic of daily bitcoin rates and wish to submit to you all and wait for learn how to do it right.
The program is working, not completely commented but I guess most of the people will understand what I did.

By the way, how do I include the code here?

Thanks

Wilson

Update
Thanks to johnh

# First write by Wilson Costrino
# free for use and change, just keep the credits, please


using LibPQ;

#
v_postgres_host = "192.168.xx.yy"; # Input the hostname here
v_postgres_dbname = "testeDB"; # input the db name here 
v_postgres_user = "wilson";   # input the postgres user
v_postgres_password = "password";  # input the password for the postgres user here 
v_port ="5432"; # input the port number of postgres db here
conn_string = "host=" *v_postgres_host *" port=" *v_port *" dbname=" *v_postgres_dbname *" user=" *v_postgres_user *" password=" *v_postgres_password *"";

using HTTP, JSON, Dates, CSV, Printf, Plots

function pegavalor()
    LinhaJson = HTTP.get("http://api.coindesk.com/v1/bpi/currentprice.json")
    jsonstruct = String(LinhaJson.body)
    jstruct = JSON.parse(jsonstruct)
    return jstruct["bpi"]["USD"]["rate_float"]
end

minutos(x) = 60*hour(x) + minute(x) + 1

global iniciando = true
global ArqNomeCompleto = " "

while true
    if minutos(now()) == 1 || iniciando
		global pontos = [0.0 for i in 1:1440]
		global var_ref = [0.0 for i in 1:1440]
		global eixox = [i for i in 1:1440]
		global variacao = [0.0 for i in 1:1440]
		
		if ArqNomeCompleto != " "
			close(arqsaida)
		end
		
		nomearq = "cotacoes_btc-"*string(Dates.today())*".csv"

		global ArqNomeCompleto = homedir()*"\\"*nomearq

		if isfile(ArqNomeCompleto)
			dt_hoje = CSV.read(ArqNomeCompleto)
		end
		global arqsaida = open(ArqNomeCompleto,"a")

		global referencia = pegavalor()
		global inicio = minutos(now())
		if second(now()) > 50
			sleep(15)
		end
		global segundo = second(now())
		
		@printf "\n\nValor de abertura = %8.2f em %d minutos com %d segundos\n\n" referencia inicio segundo
		global iniciando = false
		
		Plots.plot(2)
	end
	valor = pegavalor()
	ponto = minutos(now())
	datahora = Dates.format(now(),"\'yyyy-mm-dd HH:MM:SS\'")
	pontos[ponto] = valor
	if ponto != 1
		variacao[ponto] = (pontos[ponto-1] != 0 ? 100*(valor-pontos[ponto-1])/pontos[ponto-1] : 0.0)
	else
		variacao[ponto] = 0.0
	end
	var_ref[ponto] = 100*(valor-referencia)/referencia
	
	#abre conexĂŁo e insere

	conn = LibPQ.Connection(conn_string);
	linhasql = "INSERT INTO cotacaobt (datahora, valor) VALUES (" *datahora *"," *string(valor) *");"

	LibPQ.execute(
       conn,
       linhasql
	)

	close(conn);

	c_ponto = @sprintf("%4d",ponto)
	c_valor = @sprintf("%8.2f",valor)
	c_varia = @sprintf("%6.2f",variacao[ponto])
	c_refer = @sprintf("%6.2f",var_ref[ponto])

	print("Ponto ")
	printstyled(c_ponto,color=:light_cyan)
	print(", Valor ")
	printstyled(c_valor,color=:light_yellow)
	print(", Variacao ")
	if variacao[ponto] >= 0.0
		printstyled(c_varia,color=:light_green)
	else
		printstyled(c_varia, color=:light_red)
	end
	print(", Referencia ")
	if var_ref[ponto] >= 0.0
		printstyled(c_refer,color=:light_green)
	else
		printstyled(c_refer,color=:light_red)
	end
	println()

    println(arqsaida, string(Dates.today()), " ",c_ponto," ", c_valor," ", c_varia," ", c_refer)
    flush(arqsaida)

	subeixox = eixox[inicio:ponto]
	sub_ref = var_ref[inicio:ponto]
	sub_var = variacao[inicio:ponto]
	Plots.plot(subeixox,sub_var,label="Variacao %",linewidth=3,size=(800,450))
	Plots.display(Plots.plot!(subeixox,sub_ref, label="Referencia %",linewidth=3,title="Bitcoin inicial a US\$ $referencia em $inicio"))
	sleep(1)
	while second(now()) != segundo
		sleep(0.5)
	end
end

@wcostrino Hello and welcome. I am similar - I learned Pascal as an undergrad and Fortran as a postgrad.
But I must say this gently - Julia is not object oriented.
Indeed as a procedural type of guy you will find Julia very intuitive.

Please see here regarding quoting code

1 Like

Thanks johnh… edited the original message
included the code!

The first suggestion I would make is also the first suggestion from the Julia performance tips: avoiding global variables. While there can be legitimate uses for globals, if your goal is to improve your Julia programming skill, then practicing working without globals will be a useful exercise. It will also generally make your code run faster, sometimes by a dramatic amount.

In the case of your code, this is a matter of first wrapping all of the behavior in functions and then second thinking about how to break those up into smaller functions. That really means trying to think carefully about what are all of the pieces of information needed to accomplish some particular task and making sure that all of those pieces of information are passed in as arguments to each function.

You’re likely to then find cases where several functions are taking similar sets of arguments. That’s often a good signal that those arguments should be collected together in a struct or a mutable struct. For example, if your functions often take in a vector of dates and a vector of sale prices, then perhaps you actually need a Vector{Sale} where Sale is a struct with a date and price field.

2 Likes

Thanks for the tips, rdeits.

If you kindly change the code for an example, I will appreciate.
I am not proud of the code I did, but some of the solutions was done because my understanding of things are not in agreement with the paradigm of the language.
Global variables are used only because of the loop. If I had another solution, I will sure had imnplemented it.
2 things I did just to get the results:
1 - embedded the variables in the string to make the sql input
2 - colored the output inside the string, because the proper function was not working for me.

Again, it was an effort try to make things works and I cannot say that I fully understand functional loanguages at all.
Thats why I am asking you for help

Thanks a lot

Wilson

There’s no need to use global variables just to have a loop. Just put your code inside a function. e.g.:

julia> function sum(x)
         result = zero(eltype(x))
         for element in x
           result += element
         end
         return result
       end
sum (generic function with 1 method)

julia> sum([1,2,3])
6
1 Like

rdeits,

The fact that I am “recreating” some vectors every start of day (iniciando on the if condition inside the while) that references things outside, how do I resolve this? Am I guessing right that the structure that I have used will need global, and I will need to refactor it?