User/Console Input (read, readline, input)

,

Apologies for the newbie question.

I’m not a coder, but trying to get a little familiar with Julia. I’ve installed it on my MacBook, along with Juno and Atom.

From what I’ve been able to find, I should be able to get input from the user with “read” or “readline” or “input”. (At first, I found a google hit that showed me an “input” that I think is a user-defined function, but then later I found “input()” mentioned in the Julia/Juno in-Atom documentation.)

But my short test code-snippet is not behaving as I would expect. Here’s my code:

print("Enter your name: ")
n = readline()
println(“Your name is $n.”) # Just to test if one of these two methods behaves differently.
println("Your name is ", n, “.”) # They behave the same.

When I run my code, I’m prompted in the REPL to enter my name. I click in the REPL to give that window the focus, and then type in a name (say, Kent).

When I hit ENTER, the prompt disappears Why? I didn’t tell it to disappear.

I see my name on the screen, as I’ve entered it. It sits there forever until I hit ENTER a second time. Why am I having to hit ENTER twice?

When I do that, the REPL then displays a blank line, then my sentences, without my name, then an error, like this:

julia> Kent

Your name is .
Your name is .
julia> ERROR: UndefVarError: Kent not defined

I’ve been googling and experimenting for two days, and am no closer to understanding what is going on or how to get user input than when I began.

When

i try different code:

n = input("Enter your name: ")
println(“Your name is $n.”) # This is a comment
println("Your name is ", n, “.”) # It should be ignored.

I get to the point where I have entered my name, and then the REPL appears to become somewhat catatonic, and about all I can get to work is a Ctrl-C stopping of Julia or a Ctrl-C-generated set of error messages (no real consistency in the result).

Am I doing things wrong? Is Julia not a sufficiently general-purpose programming language to handle such a simple user-input task? Have I uncovered some Mac-based bug? Other?

Thanks!


Kent

1 Like

Your first code example works just fine for me (in the Julia REPL on a PC), so either you’re doing something weird that I can’t tell from your post, or there’s an issue with Atom reading from STDIN (i.e. user input in this case). To diagnose what is going on, please tell us how you are running your code:

  1. Are you entering it line by line?
  2. Are you copy-pasting several lines into the REPL at once?
  3. Are you running an external file using include(filename)?

Options 1 and 3 should always work no matter if you are in Julia’s own REPL or in Atom. But 2 can behave differently in Atom compared to Julia’s REPL - in Atom readline() may use the copy-pasted lines as input instead of what you type.

On a side note: I held an introduction to Julia for PhD students some weeks ago, and two of my students also instinctively wrote code that prompted for user input. That’s an extremely old-fashioned way of doing things that goes back to the days of BASIC in the 1960s. The Julian way, or the standard way for modern interactive languages in general, is to write a function that takes a user defined argument and then call that function interactively:

function sayhi(name)
    println("Hi $name, how are you?")
end

And then just call that function with your custom arguments:

julia> sayhi("Kent")
Hi Kent, how are you?

Side note 2: please use triple backticks ``` to include code in your posts in the future, here’s how and why.

Thank you for your response, NiclasMattson!

I am entering the code line-by-line within the editor window in Atom after installing the “uber-juno” package.

You got me to thinking though, that it might be some interaction within Juno and/or Atom, so I did a File/Save As to the name “bub.jl”, then opened a new Teminal window and ran “Julia bub.jl”. The program behaved exactly as I would expect it to.

So I switched over to my Debian box, installed Atom and Uber-Juno, and again typed in the three bais lines of code (no copy/paste), and when I run the code (Command-Shift-Enter), it misbehaves exaactly as I reported it doing on my Mac in my first post. Here in Debian , I again did a File/Save As (different machine, different OS, same tools, same code), and it worked perfectly, as I would expect the code to work.

So it appears that there’s something about Atom/Juno that’s … buggy. My code is good, and functional. The Atom/Juno IDE is not.

Concerning your first side-note: I don’t understand the value of writing a several-line function, with its overhead, over just using the three lines inline:

function Input(prompt)
    print(prompt)
    readline()
end

n = Input("Enter your name: ")
println("Your name is $n.")

vs.

print("Enter your name: ")
n = readline()
println("Your name is $n.")

If I were to want to reuse this feature, sure, a function makes sense. But for a one-off use, it seems the function reduces both readability and efficiency. Perhaps I’m missing something?

Concerning your second side-note, thanks! I want to do things the right way (including converting my code to a function, if indeed that’s the right way), so I appreciate you making me aware of this code-quoting feature of this forum.


Kent

1 Like

OK, if you can consistently reproduce the problem and reduce it to an MWE (minimum working example) then you may want to create an issue for it at Github. Then you can interact directly with the Juno developers and follow progress as it gets discussed and fixed. Or perhaps they’ll explain why this actually isn’t a problem with Atom/Juno. You never know. :slight_smile:

Concerning prompting, note that you can also define a short Julia function in one line like this:

sayhi(name) = println("Hi $name, how are you?")

And call it as before:

julia> sayhi("Kent")
Hi Kent, how are you?

With the convenience features of the REPL (like up arrow to bring up and edit previously typed lines) it becomes easy to re-run a function a number of times with varying input. And to benefit from Julia’s main strengths over other programming languages, e.g. execution speed and clarity of code, you should really get into the habit of putting everything in functions. But do whatever you prefer for now and note when you revisit this thread in a year or two that I told you so. :slight_smile:

The original issue is a known Juno bug:
https://github.com/JunoLab/Juno.jl/issues/118

I am not sure, is the following the same Juno bug?
The test.jl file contains this 3 lines:

while “x” != readline() >= “”
print(“running”)
end

When I run that directly with Julia, or paste the lines in the repl, the code works correctly: each time I press Enter, I get “running” printed on the console. When I press x and Enter, the loop exits. However, in Juno Julia crashes at Enter, and nothing is printed, and the Juno REPL does not react anymore.

Is there a workaround?

Except for running the code in the Juno REPL? No. Or at least I couldn’t figure one out.

The workaround that I found is to make a function and to call it in the REPL section of the JUNO/Julia environment, for example:

1:Make your function

function choice() # This little game for example
    n=1
    r=rand(1:9)
    while n != 0
        print("Guess an digit from 1 to 9 (0 to exit): ")
        n = parse(UInt8, readline())
        if n==r
            println("*****=======lucky find!=======*****")
            println("Play again...")
            r=rand(1:9)
        elseif n!=0
            println("Wrong,keep trying")
        end
    end
end

2: DO NOT try to evaluate choice() in the text editor or it will crash JUNO/Julia.

3: find the REPL part of JUNO/Julia and evaluate your function, like this for me: julia> choice()

Please let me know if this get fixed or if you have a better idea for the moment.

Does anyone know if this “print then read” REPL problem has been solved for the Mac?

These are the things that happen when you are trying to introduce others to Julia. It’s usually among the first things you try. It doesn’t make for a good introduction. Such a glaring disfunction needs prompt attention.

Is this really one of the first things you want to show people how to do in Julia? That seems… odd. This is only an issue in a very specific context—when trying to use low-level I/O functions from inside of the Juno IDE. If you’re using Julia in the terminal, it works fine. Certainly, it would be nice to fix, but it seems like a rather niche problem. In case you’re not aware, Julia ships with a fully functional interactive terminal prompt and menu system which you can also use for prompting the user for input. It seems like insisting on using low-level functions like print and readline in contexts like IDEs instead of using higher level abstractions that can hook into the appropriate display contexts is the bigger problem here.

4 Likes

Really? My experience is that newbies want to have a personal interaction with a computer and that is not selecting something from a menu but to have the computer learn their name and have the computer respond using their name. It is not complicated. I’m just making Hello World personal. The readline() works as expected in REPL on PCs but not on the Mac. I can’t see how you don’t think this is a problem.

This isn’t a Mac issue, and it’s not an issue with Julia itself but with Juno (although calling readline() asynchronously would show similar behaviour outside of Juno as well). I actually have this almost fixed locally (now readline() when evaluated in an editor just doesn’t get the first entered char).
Will let you know once the bug is fixed and I’ve pushed a new release.

Thanks pfitzseb. Fantastic, you are.

Unfortunately, it is, at the moment you depart from the implicit assumption that the REPL is a command-line process with direct access to a terminal.

Your “personalized hello world” example is indeed used as an introduction in many languages. But in Julia you can also do many other basic things that are basic, and display the comparative advantages of the language.

Eg simulate \pi:

function simulated_unit_circle_area(N)
    count_inside = 0
    for _ in 1:N
        x = rand() * 2 - 1
        y = rand() * 2 - 1
        if abs2(x) + abs2(y) ≤ 1
            count_inside += 1
        end
    end
    count_inside / N * 4
end

my_π = simulated_unit_circle_area(1000000)
1 Like

Actually, the problem is a bug and is in the process of being fixed.

Your example is too advanced for a 10 year old. In this example you have to explain what you are simulating using a dartboard example, why you are subtracting 1 from x^2 and y^2, why you are using abs2 instead of abs, that count is not being divided by N*4 and finally why π is nowhere near the result of this function even if you use a sizable N. In the case of the 10 year old, she left the room long ago.

I’m teaching Julia as a first computer language not as an alternative to Python, C or Java.

4 Likes

Under JuliaLTS it is still not working for me, at least in the REPL inside VScode :frowning:
Are there any REPL-based alternatives around?

not JuliaLTS, but in Julia 1.8.0 from the VS Code repl it seems to work OK:

julia> input(prompt::AbstractString=": ")  = begin print(prompt); return readline(); end
input (generic function with 2 methods)

julia> myname = input("Enter your name: ")
Enter your name: Mickey Mouse
"Mickey Mouse"

julia> println(myname)
Mickey Mouse
1 Like

Hi Peter,
thanks, my first mistake was to write my name without quotes.
It goes in the right direction, what I am looking for is e.g. a “yes”/“no” option.
Stefan

How about using a TerminalMenu?

julia> import REPL

julia> using REPL.TerminalMenus

julia> menu = RadioMenu(["Yes", "No"]);

julia> choice = request("Please use up/down arrows to choose an option:", menu);
Please use up/down arrows to choose an option:
 > Yes
   No

julia> choice
1

This is documented here.

1 Like