I would like to collect user input (a list of number separated by a space) split it in to an array and transform the data in it from string to float.
Basically i want to recreate this python code in Julia:
userlist = input('[+]type in a list of number separated by a space: ').split()
for i in range(len(userlist)): userlist[i] = float(userlist[i])
i tried this but didn't work:
print("type in a list of number separated by a space: ")
userinput = readline()
userlist = rsplit(userinput, " ")
for i in 0:length(userlist)
userlist[i] = userlist[i]::Float64
end
You're close. You parse a String into Float64 with parse, not a type assertion.
userlist[i] = parse(Float64, userlist[i])
This still won't quite work, since userlist is an array of strings and can't store floats (arrays in Julia are stored with their type by default, for efficiency). You could make a new array and then do the for loop like you have been, but you can also just use map.
userlist = map(x -> parse(Float64, x), userlist)
I would recommend using DelimitedFiles as it is usually more robust (you always end up with user inputting some wrong data etc.:
readdlm(IOBuffer(readline()))
For an example:
julia> readdlm(IOBuffer(readline()))
1 2 3
1×3 Matrix{Float64}:
1.0 2.0 3.0
Related
I hope I get someone who understand this. I have been trying to concatenate Julia string for quit a while now but I still have an issue. I have this loop where I am trying to concatenate the string and a number from the loop then add the new value to an array, everything is fine when I print the value in the loop but printing the arrays then all the elements of the array are split again to individual characters.
my code is as bellow
a = 1
for i in nums_loop
i_val = i[a]
append!(const_names, (string(x, string(a))))
println(string(x, string(a)))
a += 1
end
print(const_names)
the output is as bellow
X1
X2
Any['X', '1', 'X', '2']
This seems the easiest way: first initiliaze your array_names with an empty string, later removing it with popfirst! (bad practise to call the array constant if you are actually changing its content)
array_names=[" "]
num_loops=2
for i=1:num_loops
push!(array_names, "X$i")
end
popfirst!(array_names)
println(array_names)
This gives me the result:
julia> println(array_names)
["X1", "X2"]
I am trying to convert the following variable:
- final "in1.txt";
val it = [|[#"S",#".",#".",#"."],[#".",#".",#".",#"."],[#"W",#".",#"X",#"W"],
[#".",#".",#"X",#"E"]|] : char list array
from 'char list array' to 'char array array' in SMLNJ. The only reason I want to do this is because I need to be able to randomly iterate through this data, to perform a Dijkstra-like algorithm for a school project (if there 's a more efficient way to make this data iteratable, I am all ears). Is there a way to do this? The function that reads the input file and returns the above is this (I found it in Stack Overflow):
fun linelist file =
let
open Char
open String
open List
val instr = TextIO.openIn file
val str = TextIO.inputAll instr
in
tokens isSpace str
before
TextIO.closeIn instr
end
fun final file =
let
fun getsudo file = map explode (linelist file)
in
Array.fromList (getsudo file)
end
and the input files that need to be processed are like the one that follows:
S...
....
W.XW
..XE
You might want to try a different way to read this (space delivery) map (to help Lakis -- yes I am a classmate of yours).
fun parse file =
let
fun next_String input = (TextIO.inputAll input)
val stream = TextIO.openIn file
val a = next_String stream
val lista = explode(a)
in
lista
end
Parse is a function that gets all the contents from a text file and saves them in string a. Then, the function explode (function of String Signature of the SML NJ) creates a list, called lista. The elements of the list are the characters of the string a in the same order.
Then, you can create another function that saves the contents of the list to an array. Each row of the array will contain the characters of the list until #"\n" comes up.
I wanted to create a global variable called result that uses 5 string concatenations to create a string containing 9 times the string start, separated by commas.
I have two pieces of code, only the second one declares a global variable.
For some reason it's not registering easily in my brain... Is it just that i used a let in so result in the first piece of code is a local variable? Is there a more detailed explanation for this?
let start = "ab";;
let result = start ^ "," in
let result = result ^ result in
let result = result ^ result in
let result = result ^ result in
let result = result ^ start in
result;;
- : string = "ab,ab,ab,ab,ab,ab,ab,ab,ab"
let result =
let result = start ^ "," in
let result = result ^ result in
let result = result ^ result in
let result = result ^ result in
let result = result ^ start in
result;;
val result : string = "ab,ab,ab,ab,ab,ab,ab,ab,ab"
Let me to be a little bit boring person. There are no local and global variables in OCaml. This concept came from languages with different scoping rules. Also, the word "variable" itself should be taken with care. Its meaning was perverted by C-like languages. The original, mathematical, meaning of this word corresponds to a name of some mathematical object, that is used inside a formula, that represent a range of such values. In C-like languages, a variable is confused with the memory cell, that can change in time. So, to avoid the confusion let's use a more accurate terminology. Let's use word name instead of variable. Since, variables... sorry names are not memory cells, there is nothing to create. When you're using one of the let syntaxes, you're actually creating a binding, i.e., an association between a name and a value. The let <name> = <expr-1> in <expr-2> binds a value of the in the scope of the <expr-2> expression. The let <name> = <expr-1> in <expr-2> is by itself is also an expression, so, for example <expr-2> can also contain let ... in ... constructs inside, e.g.,
let a = 1 in
let b = a + 1 in
let c = b + 1 in
a + b + c
I especially, indented the code in non-idiomatic way to highlight the syntactic structure of the expression. OCaml also allows to use a name, that is already bound in the scope. The new binding will hide the existing one (that is not allowed in C, for example), e.g.,
let a = a + 1 in
let a = a + 1 in
let a = a + 1 in
a + a + a
Finally, the top-level (aka module level) let-binding (called definition in OCaml parlance), has the syntax: let <name> = <expr>, note that there is no in here. The definition binds the <name> to a result of the evaluation of <expr> in the lexical scope that extends form the point of definition to the end of the enclosing module. When you're implementing a module, you must use let <name> = <expr> to bind your code to names (you may omit name by using _). It is a little bit different from the interactive toplevel (interactive ocaml program), that actually accepts an expression, and evaluates it. For example,
let result = start ^ "," in
let result = result ^ result in
let result = result ^ result in
let result = result ^ result in
let result = result ^ start in
result
Is not a valid OCaml program (something that can be put into an ml file and compiled). Because it is an expression, not a module definition.
Is it just that i used a let in so result in the first piece of code is a local variable?
Pretty much. The syntax to define a global variable is let variable = expression without an in. The syntax to define a local variable is let variable = expression in expression which will define variable local to the expression after the in.
When you have let ... in, you're declaring a local variable. When you have just let by itself (at the top level of a module), you're declaring a global name of the module. (That is, a name that can be exported from the module.)
Your first example consists entirely of let ... in. So there is no top-level name declared.
Your second example has one let by itself, followed by several occurrences of let ... in. So it declares a top-level name result.
Let's say there is a type
immutable Foo
x :: Int64
y :: Float64
end
and there is a variable foo = Foo(1,2.0). I want to construct a new variable bar using foo as a prototype with field y = 3.0 (or, alternatively non-destructively update foo producing a new Foo object). In ML languages (Haskell, OCaml, F#) and a few others (e.g. Clojure) there is an idiom that in pseudo-code would look like
bar = {foo with y = 3.0}
Is there something like this in Julia?
This is tricky. In Clojure this would work with a data structure, a dynamically typed immutable map, so we simply call the appropriate method to add/change a key. But when working with types we'll have to do some reflection to generate an appropriate new constructor for the type. Moreover, unlike Haskell or the various MLs, Julia isn't statically typed, so one does not simply look at an expression like {foo with y = 1} and work out what code should be generated to implement it.
Actually, we can build a Clojure-esque solution to this; since Julia provides enough reflection and dynamism that we can treat the type as a sort of immutable map. We can use fieldnames to get the list of "keys" in order (like [:x, :y]) and we can then use getfield(foo, :x) to get field values dynamically:
immutable Foo
x
y
z
end
x = Foo(1,2,3)
with_slow(x, p) =
typeof(x)(((f == p.first ? p.second : getfield(x, f)) for f in fieldnames(x))...)
with_slow(x, ps...) = reduce(with_slow, x, ps)
with_slow(x, :y => 4, :z => 6) == Foo(1,4,6)
However, there's a reason this is called with_slow. Because of the reflection it's going to be nowhere near as fast as a handwritten function like withy(foo::Foo, y) = Foo(foo.x, y, foo.z). If Foo is parametised (e.g. Foo{T} with y::T) then Julia will be able to infer that withy(foo, 1.) returns a Foo{Float64}, but won't be able to infer with_slow at all. As we know, this kills the crab performance.
The only way to make this as fast as ML and co is to generate code effectively equivalent to the handwritten version. As it happens, we can pull off that version as well!
# Fields
type Field{K} end
Base.convert{K}(::Type{Symbol}, ::Field{K}) = K
Base.convert(::Type{Field}, s::Symbol) = Field{s}()
macro f_str(s)
:(Field{$(Expr(:quote, symbol(s)))}())
end
typealias FieldPair{F<:Field, T} Pair{F, T}
# Immutable `with`
for nargs = 1:5
args = [symbol("p$i") for i = 1:nargs]
#eval with(x, $([:($p::FieldPair) for p = args]...), p::FieldPair) =
with(with(x, $(args...)), p)
end
#generated function with{F, T}(x, p::Pair{Field{F}, T})
:($(x.name.primary)($([name == F ? :(p.second) : :(x.$name)
for name in fieldnames(x)]...)))
end
The first section is a hack to produce a symbol-like object, f"foo", whose value is known within the type system. The generated function is like a macro that takes types as opposed to expressions; because it has access to Foo and the field names it can generate essentially the hand-optimised version of this code. You can also check that Julia is able to properly infer the output type, if you parametrise Foo:
#code_typed with(x, f"y" => 4., f"z" => "hello") # => ...::Foo{Int,Float64,String}
(The for nargs line is essentially a manually-unrolled reduce which enables this.)
Finally, lest I be accused of giving slightly crazy advice, I want to warn that this isn't all that idiomatic in Julia. While I can't give very specific advice without knowing your use case, it's generally best to have fields with a manageable (small) set of fields and a small set of functions which do the basic manipulation of those fields; you can build on those functions to create the final public API. If what you want is really an immutable dict, you're much better off just using a specialised data structure for that.
There is also setindex (without the ! at the end) implemented in the FixedSizeArrays.jl package, which does this in an efficient way.
I'm trying to read text from a file in SML. Eventually, I want a list of individual words; however, I'm struggling at how to convert between a TextIO.elem to a string. For example, if I write the following code it returns a TextIO.elem but I don't know how to convert it to a string so that I can concat it with another string
TextIO.input1 inStream
TextIO.elem is just a synonym for char, so you can use the str function to convert it to a string. But as I replied to elsewhere, I suggest using TextIO.inputAll to get a string right away.
Here is a function that takes an instream and delivers all (remaining) words in it:
val words = String.tokens Char.isSpace o TextIO.inputAll
The type of this function is TextIO.instream -> string list.