Learning Nim and I like it resemblence of Python (but fast). In Python I can do this:
item_index = [(idx, itm) for idx, itm in enumerate(row)]
Im looking for a way to enumerate a Nim sequence so I would write this:
item_index = lc[(idx, itm) | (idx, itm <- enumerate(row))]
Does this functionality exist? I'm sure you could create it, maybe with a proc, template or macro it but I'm still very new, and these seem hard to create myself still. Here is my attempt:
iterator enumerate[T](s: seq[T]): (int, T) =
var i = 0
while i < len(s):
yield (i, s[i])
i += 1
I'm a newbie with nim, and I'm not really sure what you want, but...
If you use two variables in a for statement, you will get the index and the value:
for x, y in [11,22,33]:
echo x, " ", y
Gives:
0 11
1 22
2 33
HTH.
Related
I would like to do something like this:
Base.#kwdef mutable struct Setup
# physics
lx = 20.0
dc = 1.0
n = 4
# inital condition
ic(x) = exp(-(x-lx/4)^2)
# numerics
nx = 200
nvis = 50
# derived numerics
dx = lx/nx
dt = dx^2/dc/10
nt = nx^2 ÷ 5
# arrays
xc = LinRange(dx/2,lx-dx/2,nx)
C0 = ic.(xc)
C = copy(C)
q = zeros(nx-1)
# collections for easy use
dgl_params=[dc,n]
end
The problem here is that it says ic was undefined. Makes sense, because ic is not in the global scope.
Then I tried writing an outside constructor instead (I am not writing an inside constructor as that would overwrite the default constructor).
Base.#kwdef mutable struct Setup
# physics
lx = 20.0
dc = 1.0
n = 4
# inital condition
ic(x) = exp(-(x-lx/4)^2)
# numerics
nx = 200
nvis = 50
# derived numerics
dx = lx/nx
dt = dx^2/dc/10
nt = nx^2 ÷ 5
# arrays
xc = LinRange(dx/2,lx-dx/2,nx)
# C0 = ic.(xc)
C0
C = copy(C)
q = zeros(nx-1)
# collections for easy use
dgl_params=[dc,n]
end
function Setup()
Setup(Setup.ic(Setup.xc))
end
Setup()
But now it says DataType has no field ic which of course makes sense, I want the ic of the object itself. However there appears to be no selfor this keyword in julia.
Strangely enough the above seems to work fine with dx or dt which are also depending on other variables
Normally the design is to have multiple dispatch and functions outside of the object
When creating structs always provide the datatype of elements
For this large structs usually you will find out that using Parameters package will be more convenient when later debugging
The easiest way to circumvent the limitation is to have a lambda function in a field such as (this is however not the recommended Julia style):
#with_kw mutable struct Setup
lx::Float64 = 20.0
ic::Function = x -> lx * x
end
This can be now used as:
julia> s = Setup(lx=30)
Setup
lx: Float64 30.0
ic: #10 (function of type var"#10#14"{Int64})
julia> s.ic(10)
300
Actually, it is not in the design to have what in Java or C++ you would call "member functions". Part of this is Julia's will to benefit from the multiple dispatch programming paradigm. In Julia, mutables are pointers, so you pass them directly to a function, e.g.
function ic(setup::Setup, x)
return exp(-(x-setup.lx/4)^2)
end
That said, there is still a way to have more Java-esque classes, though not super recommended. Check this thread and, particularly, the answered marked as solution, given by one of Julia's authors themself.
Okay, I found the solution.
This does not work, because there are no methods in julia:
Base.#kwdef mutable struct S
n = 5
m
f(x) = x + 100
A = f.(randn(n,m))
end
s = S(m=5) # ERROR: UndefVarError: f not defined
s.A
s.f(5)
But this does work, because here f is a variable and not a function
Base.#kwdef mutable struct S
n = 5
m
f= x-> x + 100
A = f.(randn(n,m))
end
s = S(m=5)
s.A
s.f(5)
I am trying to pick up functional programming and decided to start with Problem 1 on Project Euler: basically add all numbers less than 1000 divisible by 3 or 5 (link: a link).
This is the code that I have written. It outputs a list of factors of 3 or 5 (still need to figure out how to sum).
import Html exposing (text)
import Array
main =
text (
toString
[findSum_maxZ 3 5 1000]
)
findSum_maxZ x y max_z =
Array.filter isDivisible_x_or_y (Array.initialize max_z identity)
isDivisible_x_or_y x =
if x % 3 == 0 || x % 5 == 0 then True else False
My issue is that I reference 3 and 5 twice but I cannot call isDivisible with the additional parameters of the more abstract 'x' and'y'. My goal is to determine effective methods of removing these artificially mutable values so the end user only has to modify each input value once. Any advice?
I apologize if this question is dumb, there is not a lot of information on ELM available (especially compared to python, c, c++, java, etc which I have used) and I am still not fully comfortable with the functional programming jargon. Any and all help is appreciated.
The cool thing about ML languages is that you are pretty much free to build your own "dialect" to solve problems.
You can use currying to apply just the x and y arguments to your function, creating a new function where the supplied values are already set.
import Html exposing (text)
import Array
main = [findSum 3 5 1000]
|>toString
|>text
findSum x y maxZ =
let
isDivisibleByX = isDivisible x
isDivisibleByY = isDivisible y
in
Array.initialize maxZ identity
|>Array.filter isDivisibleByX
|>Array.filter isDivisibleByY
--as you can see, it is possible to use a list instead of creating
--new functions, it is up to you to check which abstraction works
--the best
isDivisible a b =
b % a == 0
You can also work with a single function, without resorting to currying:
import Html exposing (text)
import Array
main = [findSum 3 5 1000]
|>toString
|>text
findSum x y maxZ =
Array.initialize maxZ identity
|>Array.filter (\n-> isDivisible x n ) --or just (isDivisible x)
|>Array.filter (\n-> isDivisible y n)
isDivisible a b =
b % a == 0
If you want to filter the array with just one line, you can do this:
import Html exposing (text)
main = findSum 3 5 1000
|>toString
|>text
findSum x y maxZ =
let
divisibles = \n-> isDivisible x n && isDivisible y n
in
List.range 0 maxZ
|>List.filter divisibles
isDivisible a b =
b % a == 0
The most direct answer to your question is that you can have isDivisible_x_or_y take the two factors, and then use currying to pass the partially applied function to Array.filter.
That is, you can define isDivisible_x_or_y like this (I also removed the if True then True else False syntax and just return the expression directly):
isDivisible_x_or_y x y val =
val % x == 0 || val % y == 0
Currying is the ability to only supply some of the parameters to a function, and get back a function that takes the rest of the parameters. So, the type definition of isDivisible_x_or_y is Int -> Int -> Int -> Bool (that is, it takes in three Int values and returns a Bool). If we supply values for the x and y arguments (e.g. isDivisible_x_y 3 5), we now get a function with the type definition of Int -> Bool. This is the type expected by Array.filter.
You can see a working example at https://ellie-app.com/sdxWFL9ynka1
Another couple of notes:
List is much more common than Array in Elm. You would only use Array if you need to get items at specific indexes. Instead of Array.initialize, you can use List.range
Using the pipeline operator |> can often make your code a lot simpler to read. Instead of text (toString (getValue)), you have getValue |> toString |> text, which is now in the order that the operations occur, and doesn't have extra parenthesis. This whole program could be one simple pipeline (in a lot of scenarios putting everything into one pipeline can be excessive, though):
main =
List.range 0 max_z
|> List.filter (isDivisible_x_or_y 3 5)
|> toString
|> text
isDivisible_x_or_y x y val =
val % x == 0 || val % y == 0
Like in R:
a <- 2
or even better
a ← 2
which should translate to
a = 2
and if possible respect method overloading.
= is overloaded (not in the multiple dispatch sense) a lot in Julia.
It binds a new variable. As in a = 3. You won't be able to use ← instead of = in this context, because you can't overload binding in Julia.
It gets lowered to setindex!. As in, a[i] = b gets lowered to setindex!(a, b, i). Unfortunately, setindex! takes 3 variables while ← can only take 2 variables. So you can't overload = with 3 variables.
But, you can use only 2 variables and overload a[:] = b, for example. So, you can define ←(a,b) = (a[:] = b) or ←(a,b) = setindex!(a,b,:).
a .= b gets lowered to (Base.broadcast!)(Base.identity, a, b). You can overload this by defining ←(a,b) = (a .= b) or ←(a,b) = (Base.broadcast!)(Base.identity, a, b).
So, there are two potentially nice ways of using ←. Good luck ;)
Btw, if you really want to use ← to do binding (like in 1.), the only way to do it is using macros. But then, you will have to write a macro in front of every single assignment, which doesn't look very good.
Also, if you want to explore how operators get lowered in Julia, do f(a,b) = (a .= b), for example, and then #code_lowered f(x,y).
No. = is not an operator in Julia, and cannot be assigned to another symbol.
Disclaimer: You are fully responsible if you will try my (still beginner's) experiments bellow! :P
MacroHelper is module ( big thanks to #Alexander_Morley and #DanGetz for help ) I plan to play with in future and we could probably try it here :
julia> module MacroHelper
# modified from the julia source ./test/parse.jl
function parseall(str)
pos = start(str)
exs = []
while !done(str, pos)
ex, pos = parse(str, pos) # returns next starting point as well as expr
ex.head == :toplevel ? append!(exs, ex.args) : push!(exs, ex)
end
if length(exs) == 0
throw(ParseError("end of input"))
elseif length(exs) == 1
return exs[1]
else
return Expr(:block, exs...) # convert the array of expressions
# back to a single expression
end
end
end;
With module above you could define simple test "language":
julia> module TstLang
export #tst_cmd
import MacroHelper
macro tst_cmd(a)
b = replace("$a", "←", "=") # just simply replacing ←
# in real life you would probably like
# to escape comments, strings etc
return MacroHelper.parseall(b)
end
end;
And by using it you could probably get what you want:
julia> using TstLang
julia> tst```
a ← 3
println(a)
a +← a + 3 # maybe not wanted? :P
```
3
9
What about performance?
julia> function test1()
a = 3
a += a + 3
end;
julia> function test2()
tst```
a ← 3
a +← a + 3
```
end;
julia> test1(); #time test1();
0.000002 seconds (4 allocations: 160 bytes)
julia> test2(); #time test2();
0.000002 seconds (4 allocations: 160 bytes)
If you like to see syntax highlight (for example in atom editor) then you need to use it differently:
function test3()
#tst_cmd begin
a ← 3
a ← a + a + 3 # parser don't allow you to use "+←" here!
end
end;
We could hope that future Julia IDEs could syntax highlight cmd macros too. :)
What could be problem with "solution" above? I am not so experienced julian so many things. :P (in this moment something about "macro hygiene" and "global scope" comes to mind...)
But what you want is IMHO good for some domain specific languages and not to redefine basic of language! It is because readability very counts and if everybody will redefine everything then it will end in Tower of Babel...
I would like to know how to overload a function in scilab. It doesn't seem to be as simple as in C++. For example,
function [A1,B1,np1]=pivota_parcial(A,B,n,k,np)
.......//this is just an example// the code doesn't really matter
endfunction
//has less input/output variables//operates differently
function [A1,np1]=pivota_parcial(A,n,k,np)
.......//this is just an example// the code doesn't really matter
endfunction
thanks
Beginner in scilab ....
You can accomplish something like that by combining varargin, varargout and argn() when you implement your function. Take a look at the following example:
function varargout = pivota_parcial(varargin)
[lhs,rhs] = argn();
//first check number of inputs or outputs
//lhs: left-hand side (number of outputs)
//rhs: right-hand side (number of inputs)
if rhs == 4 then
A = varargin(1); B = 0;
n = varargin(2); k = varargin(3);
np = varargin(4);
elseif rhs == 5 then
A = varargin(1); B = varargin(2);
n = varargin(3); k = varargin(4);
np = varargin(5);
else
error("Input error message");
end
//computation goes on and it may depend on (rhs) and (lhs)
//for the sake of running this code, let's just do:
A1 = A;
B1 = B;
np1 = n;
//output
varargout = list(A1,B1,np1);
endfunction
First, you use argn() to check how many arguments are passed to the function. Then, you rename them the way you need, doing A = varargin(1) and so on. Notice that B, which is not an input in the case of 4 inputs, is now set to a constant. Maybe you actually need a value for it anyways, maybe not.
After everything is said and done, you need to set your output, and here comes the part in which using only varargout may not satisfy your need. If you use the last line the way it is, varargout = list(A1,B1,np1), you can actually call the function with 0 and up to 3 outputs, but they will be provided in the same sequence as they appear in the list(), like this:
pivota_parcial(A,B,n,k,np);: will run and the first output A1 will be delivered, but it won't be stored in any variable.
[x] = pivota_parcial(A,B,n,k,np);: x will be A1.
[x,y] = pivota_parcial(A,B,n,k,np);: x will be A1 and y will be B1.
[x,y,z] = pivota_parcial(A,B,n,k,np);: x will be A1, y will be B1, z will be np1.
If you specifically need to change the order of the output, you'll need to do the same thing you did with your inputs: check the number of outputs and use that to define varargout for each case. Basically, you'll have to change the last line by something like the following:
if lhs == 2 then
varargout = list(A1,np1);
elseif lhs == 3 then
varargout = list(A1,B1,np1);
else
error("Output error message");
end
Note that even by doing this, the ability to call this functions with 0 and up to 2 or 3 outputs is retained.
Im looking for a function like Pythons
"foobar, bar, foo".count("foo")
Could not find any functions that seemed able to do this, in a obvious way. Looking for a single function or something that is not completely overkill.
Julia-1.0 update:
For single-character count within a string (in general, any single-item count within an iterable), one can use Julia's count function:
julia> count(i->(i=='f'), "foobar, bar, foo")
2
(The first argument is a predicate that returns a ::Bool).
For the given example, the following one-liner should do:
julia> length(collect(eachmatch(r"foo", "bar foo baz foo")))
2
Julia-1.7 update:
Starting with Julia-1.7 Base.Fix2 can be used, through ==('f') below, as to shorten and sweeten the syntax:
julia> count(==('f'), "foobar, bar, foo")
2
What about regexp ?
julia> length(matchall(r"ba", "foobar, bar, foo"))
2
I think that right now the closest built-in thing to what you're after is the length of a split (minus 1). But it's not difficult to specifically create what you're after.
I could see a searchall being generally useful in Julia's Base, similar to matchall. If you don't care about the actual indices, you could just use a counter instead of growing the idxs array.
function searchall(s, t; overlap::Bool=false)
idxfcn = overlap ? first : last
r = findnext(s, t, firstindex(t))
idxs = typeof(r)[] # Or to only count: n = 0
while r !== nothing
push!(idxs, r) # n += 1
r = findnext(s, t, idxfcn(r) + 1)
end
idxs # return n
end
Adding an answer to this which allows for interpolation:
julia> a = ", , ,";
julia> b = ",";
julia> length(collect(eachmatch(Regex(b), a)))
3
Actually, this solution breaks for some simple cases due to use of Regex. Instead one might find this useful:
"""
count_flags(s::String, flag::String)
counts the number of flags `flag` in string `s`.
"""
function count_flags(s::String, flag::String)
counter = 0
for i in 1:length(s)
if occursin(flag, s)
s = replace(s, flag=> "", count=1)
counter+=1
else
break
end
end
return counter
end
Sorry to post another answer instead of commenting previous one, but i've not managed how to deal with code blocks in comments :)
If you don't like regexps, maybe a tail recursive function like this one (using the search() base function as Matt suggests) :
function mycount(what::String, where::String)
function mycountacc(what::String, where::String, acc::Int)
res = search(where, what)
res == 0:-1 ? acc : mycountacc(what, where[last(res) + 1:end], acc + 1)
end
what == "" ? 0 : mycountacc(what, where, 0)
end
This is simple and fast (and does not overflow the stack):
function mycount2(where::String, what::String)
numfinds = 0
starting = 1
while true
location = search(where, what, starting)
isempty(location) && return numfinds
numfinds += 1
starting = location.stop + 1
end
end
one liner: (Julia 1.3.1):
julia> sum([1 for i = eachmatch(r"foo", "foobar, bar, foo")])
2
Since Julia 1.3, there has been a count method that does exactly this.
count(
pattern::Union{AbstractChar,AbstractString,AbstractPattern},
string::AbstractString;
overlap::Bool = false,
)
Return the number of matches for pattern in string.
This is equivalent to calling length(findall(pattern, string)) but more
efficient.
If overlap=true, the matching sequences are allowed to overlap indices in the
original string, otherwise they must be from disjoint character ranges.
│ Julia 1.3
│
│ This method requires at least Julia 1.3.
julia> count("foo", "foobar, bar, foo")
2
julia> count("ana", "bananarama")
1
julia> count("ana", "bananarama", overlap=true)
2