Parse string as tuple

I am trying to write a function that converts a string to a tuple. This is my code:
parsetuple(p::String) = Tuple(Float64(x) for x in p)

This code can convert a string or a vector of string type to a tuple, but this doesn’t work for the example below. How can I convert A as shown below in to a tuple?
This requires recognising the , separater is defining a vector.
A = "[1.1,2.2]" or if A was instead given as A = "1.1,2.2"

The reason the above function will fail is that it will recognise A as one string and not a vector. The value for A is being passed as argument from the command line so by default it recognises everything as string.

How can I make my function flexible to be able to return a tuple when input is given as e.g. by
A = "1.1" or A = "[1.1,2.2]"?

This is converting each character in the string p to a Float64 (using the numeric value of the character’s Unicode codepoint), which sounds like it is not what you want.

Of course, there are many ways to do what you want, e.g.

parsetuple(s::AbstractString) = Tuple(parse.(Float64, split(s, ',')))

will work on comma-delimited strings like "1.1, 2.2". If you want to handle brackets too you’ll need to work a little harder to strip those off.

What is the context here? Why are you passing around small tuples of numbers in string form?

PS. A tuple may be a poor choice of data structure in a context like this where the length is determined at runtime. Normally one would use an array in such cases.

3 Likes

For string input from the terminal, what about:

print("Enter a number or array: ")
A = eval(Meta.parse(readline()))

And if one needs a tuple, then add:
Tuple(A)

I’m usually wary of using eval directly on user inputs, because it could execute arbitrary code. In some contexts the user is trusted, of course.

4 Likes

In my case, the greatest danger is myself :slight_smile:

1 Like

Thank you. I have slightly modified your answer to:
parsetuple(s::AbstractString) = occursin(",",s) ? Tuple(parse.(Float64, split(s, ','))) : parse(Float64,s)

I have a function with two methods;

  1. function compute(a,b,c::Tuple{Float64,Float64})
  2. function compute(a,b,c::Float64)

The second function expects a single value for the variable c, and the first a tuple. The length of the tuple is 2.

The reason I am passing tuples of numbers in string form is because when I call Julia from Excel using the Shell command, all the arguments are passed as strings by default and I have to convert numerical arguments to Float64 or Int64 as appropriate.

In the main Julia function that runs the whole code, e.g. I put the following lines:
file1 = ARGS[1]; var_b = ARGS[2]; t = parse(Float64,ARGS[3])
before calling that function.

Is there a better way of parsing these arguments, (e.g., so as to avoid conversion from strings to numbers)?