Hello,
The contents of the file.txt file is as follows:
1 2 3 4 5 6 7 8 9 10
I wrote the following code to put the numbers in the file into an array:
function arrayandfile()
array = fill(0,10)
inn = open("file.txt","r")
counter = 1
while !eof(inn)
c = read(inn,Char)
if c != ' '
array[counter] = parse(Int,c)
counter +=1
end
end
return(array)
end
println(arrayandfile())
GunnarFarneback is right. In this case, I would recommend that you just read in the entire txt file and then process certain lines in it as needed. That’s how I got it when I did Atcoder.
When dealing with data like 1 2 3 4 5 6 7 8 9 10, first read the line in its entirety and then separate all the numbers with the split(), which is the Julia style of writing. Your writing style is somewhat like C.
By the way, the title of the thread is wrong/misleading: you’re attempting to access an X-element Vector{Int64} at index [X + 1] (for X == 10). As Julia is 1-indexed, accessing at index X == length(...) is completely fine.
Hello,
Thank you so much for your reply.
I changed the code as follows:
function arrayandfile()
array = fill(0,10)
counter = 1
for line in eachline("file.txt")
if line != ' '
array[counter] = parse.(Int, split(line))
counter +=1
end
end
return(array)
end
println(arrayandfile())
I got:
ERROR: LoadError: MethodError: Cannot `convert` an object of type Vector{Int64} to an object of type Int64
What’s happening here is that parse.(Int, split(line)) gives you a Vector{Int} (namely, [1, 2, ..., 10]), which you’re trying to assign to the single Int at array[counter].
You could use
function arrayandfile()
array = fill(0, 10) # where 10 is the total number of values in the file
counter = 0 # number of values actually put in array so far
for line in eachline("file.txt")
line_values = parse.(Int, split(line))
array[counter + 1 : counter + length(line_values)] .= line_values
counter += length(line_values)
end
return array
end
I’ve removed the line != ' ' check, as
it’s no longer necessary as split takes care of the spaces
line, being a String, will never equal ' ' (also note that " " != ' ').
You could also go full-on vectorisation and write this as a one-liner
reduce(vcat, parse.(Int, split(line)) for line in eachline("file.txt"))
E.g.
julia> reduce(vcat, parse.(Int, split(line)) for line in eachline(IOBuffer("1 2 3\n4 5 6 7 8\n9 10")))
10-element Vector{Int64}:
1
2
3
4
5
6
7
8
9
10
Thanks again.
I’m a newbie and your code is a little difficult for me to understand.
1- If counter=1, then the line array[counter] = parse.(Int, split(line)) places the number 1 in cell 1 of the array. Am I right?
2- I changed the code as follows, removed the (counter) and the problem was fixed:
function arrayandfile2()
array = fill(0,10)
for line in eachline("file.txt")
if line != ' '
array = parse.(Int, split(line))
end
end
return(array)
end
println(arrayandfile())
No. The dot at the end of parse. means we are broadcasting the parse statement, resulting in a Vector. So the left-hand side of the assignment is an Int, but the right-hand side is a Vector{Int}.
One of the neat aspects of Julia is its interactivity in the REPL. You could debug by just checking all variables involved, via
julia> array = fill(0,10)
10-element Vector{Int64}:
0
0
0
0
0
0
0
0
0
0
julia> counter = 1
1
julia> line = first(eachline(IOBuffer("1 2 3 4 5 6 7 8 9 10"))) # or your file
"1 2 3 4 5 6 7 8 9 10"
julia> line != ' '
true
julia> array[counter] = parse.(Int, split(line))
ERROR: MethodError: Cannot `convert` an object of type Vector{Int64} to an object of type Int64
The function `convert` exists, but no method is defined for this combination of argument types.
Closest candidates are:
convert(::Type{T}, ::T) where T<:Number
@ Base number.jl:6
convert(::Type{T}, ::T) where T
@ Base Base.jl:126
convert(::Type{T}, ::AbstractChar) where T<:Number
@ Base char.jl:185
...
Stacktrace:
[1] setindex!(A::Vector{Int64}, x::Vector{Int64}, i::Int64)
@ Base .\array.jl:987
[2] top-level scope
@ REPL[5]:1
julia> array[counter]
0
julia> split(line)
10-element Vector{SubString{String}}:
"1"
"2"
"3"
"4"
"5"
"6"
"7"
"8"
"9"
"10"
julia> parse.(Int, split(line))
10-element Vector{Int64}:
1
2
3
4
5
6
7
8
9
10
julia> typeof(array[counter])
Int64
julia> typeof(parse.(Int, split(line)))
Vector{Int64} (alias for Array{Int64, 1})
Alternatively, you could also of course use something like Debugger.jl, though I find it a bit harder to get used to.
Now within each iteration step you’re creating a new variable called array holding our Vector{Int} from the parse.. This will work in this case, but not if you have multiple lines. Only the value in the last iteration step will be returned.
This is a vector of length 10, instead of receiving it with array[counter], use array = parse.(Int, split(line)). What you wrote in the second question is correct, but limited to the file being only one line.
Want to know if a file has multiple lines?
If there’s something else you don’t understand, go ahead and ask a question.
A vector is an elementary mathematical concept that represents a directed line segment. The mathematical notation is denoted as v.
The length of the projection of a vector on each axis is the vector’s component. e.g. v = [1,2,3].
Clearly, the components of a vector are scalars.
What is called the dimension of a vector in mathematics refers in programming to the length of the vector, i.e., the number of components of the vector. length(v)=3
Here are some common uses of vectors in julia.
v=[1,2,3] # typeof(v)=Vector{Int64}
v[1]=10 # now v=[10,2,3]
v[2:3]=[4,6] # now v=[10,4,6]
v2=dot(v,v) # cross product of vectors
v3=v.*v # dot product of vectors
Vector is just one-dimensional array. see doc Base.Vector e.g., Vector{T} is alias for Array{T, 1} where T is type of elements it holds and 1 means it’s one dimensional.
I doubt invoking linear algebra is the easiest way to explain the notion of Vector in Julia . (Also, I’d define a mathematical vector simply as an element of a vector space, which in turn is a triple consisting of a set and two operations, satisfying certain properties.)
If you insist on referring to mathematics, a Vector{Int} of length N \in \mathbb{N} is just an element of \mathbb{Z}^N (if you ignore the differences between \mathbb{Z} and the set of Ints).
By the way, note that \mathbb{Z}^N is not a vector space, though it is a subset (and subgroup) of the vector space \mathbb{R}^N. Something like a Vector{String} clearly also does not correspond to some vector space.
I would just explain a Vector as a finite sequence of ‘things’. A Vector{Int} is a finite sequence of Ints, a Vector{String} a finite sequence of Strings, a Vector{Any} a finite sequence of whatever your heart desires.
Obviously dot(v, v) is the dot (inner) product of v with itself (a.k.a. v ⋅ v ). The result is a scalar (Int here). To be able to use dot and ⋅ you first need to import LinearAlgebra.
v .* v is the elementwise product of v with itself. The result is a Vector satisfying (v .* v)[i] == v[i] * v[i] for i \in \{1, 2, 3\}.
cross(v, v) (v × v) is the cross product of v with itself. In general, for two Vectors v and wof length 3, v × w is another Vector of length 3. But v × v consists of zeros. You need to import LinearAlgebra to use cross and ×.
Again no. (Also, broadcasting is a proper, awesome feature, not a bug. It does not need fixing .)
You can view
save = parse.(Int, split(line)) # Note the dot .
as shorthand for
splt = split(line)
save = Vector{Int}(undef, length(splt))
for i = 1:length(splt)
save[i] = parse(Int, splt[i]) # Note there's no dot
end
Then array[counter] = save attempts to put this entire Vector{Int}save (a sequence of 10 Ints) into array[counter] where we have room for only a single Int. So this will cause an error.
The word “ten” has three letters (or characters) in it; t, e, n. The text “10” has two characters: 1, 0. The roman numeral “X” is just one letter. All are ways of writing down and communicating a particular idea to humans — once we read it we get the concept of a single number in our minds.
Julia — and nearly all programming languages — have a distinction between strings (sequences of characters like "ten" and "10") and numbers (without quotes: 10). When you parse a bit of text (a String) into an Int, you’re doing the work to interpret that text as a number. It’s a single value at that point, and it could be as large as a few quintillions (or negative, too).