Julia Lang: Error? Initializing Nullable Arrays - arrays

I am trying to initialize an array of Nullable Integers with a given size. My intend is to add elements to the array and to be able to count the number of Nullable elements in an array.
However I noticed the following behavior. Running the following code:
function main()
arr = Array{Nullable{Int}}(10)
res = 0
for i in 1:10
if isnull(arr[i])
res += 1
end
end
res
end
is expected to return 10, however the program returns different values almost every time that I run the code. Initializing just the array:
function main()
arr = Array{Nullable{Int}}(10)
end
this is the result:
Nullable{Int64}(7142821636481377634)
Nullable{Int64}(8803814271447229814)
Nullable{Int64}(7935455170894001012)
Nullable{Int64}(8247625210579135584)
Nullable{Int64}(7815275285807655200)
Nullable{Int64}()
Nullable{Int64}()
Nullable{Int64}()
Nullable{Int64}()
Nullable{Int64}()
Here one can see that not all elements are in fact not Null. Which would explain why the function isnull() does not recognize them as Null objects.
This is the desired effect:
function main()
arr = Array{Nullable{Int}}(10)
for i in 1:10
arr[i] = Nullable{Int}()
end
println(arr)
end
which indeed returns an array of Nullable elements. However, it seems a bit tedious to run this code for initialization.
Any ideas how this can be avoided?

In Julia 0.6 you can use arr = fill(Nullable{Int64}(),10).
Note however that Nullables are depreciated in Julia 0.7 (https://github.com/JuliaLang/julia/blob/master/NEWS.md), consider to use the Nothing or Missing types instead:
julia> vector_with_nothing_or_int = Vector{Union{Int64, Nothing}}(nothing,10)
10-element Array{Union{Nothing, Int64},1}:
nothing
nothing
[...]
julia> vector_with_missing_or_int = Vector{Union{Int64, Missing}}(missing,10)
10-element Array{Union{Missing, Int64},1}:
missing
missing
[...]
Check if a element is nothing or missing can be done with:
julia> vector_with_nothing_or_int[1] == nothing
true
julia> ismissing(vector_with_missing_or_int[1])
true
The Missing type also works in Julia 0.6 if you load the module Missings. This is the corresponding code for Julia 0.6:
using Missings
vector_with_missing_or_int = Vector{Union{Int64, Missing}}(10)
vector_with_missing_or_int .= missing
vector_with_nothing_or_int = Vector{Union{Int64, Nothing}}(10)
vector_with_nothing_or_int .= nothing
The operator .= replaces every element of the array with the element of the right. All these examples also work for multi-dimensional arrays if you replace Vector by Array when you specify also the number of dimensions.

Related

MethodError: no method matching -(::Int64, ::Array{Int64,1})

I tried playing around with this example in the Julia documentation. My attempt was to make the cell split into two parts that have half of the amount of protein each.
using OrdinaryDiffEq
const α = 0.3
function f(du,u,p,t)
for i in 1:length(u)
du[i] = α*u[i]/length(u)
end
end
function condition(u,t,integrator) # Event when event_f(u,t) == 0
1-maximum(u)
end
function affect!(integrator)
u = integrator.u
idxs = findall(x->x>=1-eps(eltype(u)),u)
resize!(integrator,length(u)+length(idxs))
u[idxs] ./ 2
u[end-idxs:end] = 0.5
nothing
end
callback = ContinuousCallback(condition,affect!)
u0 = [0.2]
tspan = (0.0,10.0)
prob = ODEProblem(f,u0,tspan)
sol = solve(prob,Tsit5(),callback=callback)
I get the error: MethodError: no method matching -(::Int64, ::Array{Int64,1}). I know there is a problem with idxs = findall(x->x>=1-eps(eltype(u)),u), and my attempt was to put a dot between the 1 and eps, but that didn't fix it. I am using Julia 1.1.1.
Running your code the stacktrace points to the line
u[end-idxs:end] = 0.5
The issue here is that findall returns an array even when it only finds one element, e.g.
julia> findall(x -> x > 2, [1,2,3])
1-element Array{Int64,1}:
3
and you can't subtract an array from end in your indexing expression.
I don't understand enough about your code to figure out what idxs should be, but if you expect this to only return one element you could either use first(idxs) (or even only(idxs) in Julia 1.4), or replace findall with findfirst, which returns the index as an Integer (rather than an array).

defining array from worksheet not working in filter () lines with type mismatch error

I'm using secondarray as range of cells in a worksheet (Ex. "1", "2") to exclude them as autofilter list that I'm defining in the below function in "filtercriteria".
I get "type mismatch" error in the filter (secondarray) line for some reason, but I works flawlessly when I define an array using a list of items instead. For example, if I use below line to define secondarray instead.
secondarray = ("1", "2")
I've researched similar postings and wasn't lucky, can someone help with this instance?
Thanks,
Dim secondArray As Variant
secondArray = Range("L76:M76").Value
c = 0
k = 0
count = 0
rowNumb = Worksheets("List").Range(Worksheets("List").Range("L5"), Worksheets("List").Range("L5").End(xlDown)).Rows.count
For L = 1 To rowNumb
c = Worksheets("List").Range("L5").Offset(L)
If c <> k Then
'check the current activity type against the array of types we don’t want. If it isn’t in the array we add it to an array that will be used as the filter criteria
If UBound(Filter(secondArray, c)) = -1 Then
ReDim Preserve filterCriteria(0 To count)
filterCriteria(count) = c
count = count + 1
End If
k = c
End If
Next
It isn't working because filter function takes a One-dimensional array of strings to be searched for its sourcearray argument.
When you read in a range from the sheet you automatically get a 2d array as opposed to the 1D you have when assigning from a list.
Find a way to use a 1D array to pass in
For example, as your data is coming from 1 row then slice the array by row
UBound(Filter(Application.WorksheetFunction.Index(secondArray, 1, 0), c)) = -1
You may need to find the right method for you.
Another method is given here.

How can I duplicate and delete from an array without changing the original one?

My goal is to write a method, trickysum(n) that does the following:
The method takes range of numbers 1 through n. The method then finds pairs of numbers in that range that meet a tricky qualification: The product of the pair of numbers must be equal to the sum of all numbers in the range, excluding this pair. The method then returns all number pairs that meet this qualification. Here is the expectation:
trickysum(26)
#=>[(15, 21), (21, 15)]
Here is the code I have so far:
def trickysum(n)
result = []
arr = (1..n).to_a
0.upto(arr.length - 1) do |x|
0.upto(arr.length - 1) do |y|
prod = arr[x] * arr[y]
#I create a new array to delete from to not affect the original
#array. Would also love an easier way to do this :)
new_arr = arr
new_arr.delete(new_arr[x])
new_arr.delete(new_arr[y])
sum = new_arr.inject(:+)
if sum == prod
result << "(#{arr[x]},#{arr[y]})"
end
end
end
result
end
I've looked over this code over and over and can't figure out why I'm getting the following error:
nil can't be coerced into Fixnum
(repl):7:in `*'
(repl):7:in `block (2 levels) in trickysum'
(repl):6:in `upto'
(repl):6:in `block in trickysum'
(repl):5:in `upto'
(repl):5:in `trickysum'
(repl):20:in `<main>'
Where am I going wrong?
Replace:
new_arr = arr
With:
new_arr = arr.dup
What's happening here is that you have created a shallow copy of the arr variable. Without explicitly duplicating the value, both new_arr and arr share the same location in memory.
Because of this, when you call new_arr.delete(new_arr[x]) and new_arr.delete(new_arr[y]), not only are you mutating the new array, but also the old one.
This means arr gets shorter in length, so your outer loop goes beyond its final value and you get a nil; hence the error.
With that said, I would have written this method totally differently, which would have avoided such subtle errors:
def trickysum(n)
sum = (1..n).inject(:+)
(1..n).combination(2).select do |a, b|
(a * b) + a + b == sum
end
end
Ruby is a very expressive language. If you find yourself doing looping within loops, declaring temporary variables and appending to an array of results ... Then there's probably a much more elegant solution :)

Array operations that changes the order of element in scala

In scala documentation it states that Lists are immutable and "you can rely on the fact that accessing the same collection value repeatedly at different points in time will always yield a collection with the same elements" On the other hand in arrays (mutable) some operations can change the element. Can you give me some array examples for those operations that changes element by comparing with example on lists?
val arr = Array(3,5,7)
arr(1) = 0 // arr is now Array(3,0,7)
val lst = List(3,5,7)
lst(1) = 0 // error: value update is not a member of List[Int]

ruby array of arrays, [] operator

out_file = File.open "out_file.txt" , 'w' do |f|
matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
]
f.puts "matrix test"
f.puts " int at [0,2]: #{matrix[0][2]}"
f.puts " int at [2,0]: #{matrix[2][0]}"
f.puts " int at {1,1]: #{matrix[1][1]}"
above code produces this:
"matrix test
int at [0,2]: 3
int at [2,0]: 7
int at {1,1]: 5"
but this code using the same matrix variable declaration ..
rows = Array(0..3)
cols = Array(0..3)
rows.each do |r|
cols.each do |c|
f.puts "row:#{r} col:#{c} = #{matrix[r][c]},"
end
end
produces an error:
undefined method `[]' for nil:NilClass (NoMethodError)
Can anybody please tell me what's going on?
The problem is your Array(0..3), it is generating an array [0,1,2,3] instead of what you want: [0,1,2].
You actually want to use ... : Array(0...3) => [0,1,2].
Or you could just change the range inside to 0..2 : Array(0..2) => [0,1,2]
Check out the documentation for Range for more information.
As Tony suggests, using rows=Array(0..2) or rows=Array(0...3) will work for you.
You can also use the range directly and forgo the array creation, like this:
rows = 0...3
cols = 0...3
...
There are 2 types of ranges, the inclusive .. and the exclusive ... which doesn't include the right most digit.
A range such as 0..5 will have every number including the 5. (ie. 0,1,2,3,4,5)
A range such as '0...5' will have every number excluding the 5. (ie. 0,1,2,3,4).
So if you notice your error message,
undefined method `[]' for nil:NilClass (NoMethodError)
You need to begin to wonder what could be running a method on nil. Well, you have this matrix declaration of:
matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
]
So that when this range pops up that is expressed as:
rows = Array(0..3)
It will go through 0,1,2, and also 3. Well, there is no 3 index in that array since your array begins counting at 0 and ends at 2. So when the 3 index hits, the value of it is beyond anything you've declared - it's nil. When you try to run that method on it (to call the spot in the array you want), the error message tells you that you can't run a method (which the [] is actually) on nil.
Paying close attention to your error messages, as well as understanding the 2 types of ranges should help you catch these sorts of errors in the future as well. Leave a comment if this doesn't make total sense.
The previous answers are right, but I thought I would raise the issue of the approach...
Why are you creating ranged arrays instead of using the actual length of the matrix arrays in question...?
Maybe something like this would remove the need to assume the matrix's composition:
out_file = File.open "out_file.txt" , 'w' do |f|
matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
]
f.puts "matrix test"
matrix.length.times do |r|
matrix[r].length.times do |c|
f.puts "row:#{r} col:#{c} = #{matrix[r][c]},"
end
end

Resources