digitalmars.D.learn - Circle Calculator Help
- Alexander (107/107) Jun 26 2012 Hello everybody!
- Alexander (9/9) Jun 26 2012 By the way, this is just my 2nd program in D.
- Adam D. Ruppe (3/3) Jun 26 2012 You should be able to just do a readln() before exiting
- Alexander (5/8) Jun 26 2012 I just tried that, and it still closed right after I typed the
- Steven Schveighoffer (20/45) Jun 26 2012 I'm assuming you are running on Windows. Windows with console output wi...
- Timon Gehr (3/40) Jun 26 2012 I want the two examples to generate comparable code.
- Alexander (24/24) Jun 26 2012 So, I've taken out the loop part that is "interesting" and
- Alexander (2/10) Jun 26 2012 Thanks!
- Steven Schveighoffer (7/24) Jun 26 2012 Oh, readln includes the newline by default, so to!float is choking on th...
- bearophile (7/9) Jun 26 2012 Similar things happen often. But Andrei says this is good,
- Steven Schveighoffer (11/17) Jun 26 2012 I agree with Andrei, there is no outlet for errors in the to!T function,...
- Alexander (2/2) Jun 26 2012 That must be why, I didn't import std.string!
- bearophile (26/35) Jun 26 2012 Maybe I was not clear enough, so let me explain a bit better.
- Steven Schveighoffer (26/61) Jun 26 2012 Right, but what if it's an error in your code if whitespace is present? ...
- Sean Kelly (9/21) Jun 26 2012 function, exception is the logical choice.
- Steven Schveighoffer (11/32) Jun 26 2012 That was my original suggestion. It fixes the problem, but can seem qui...
- Timon Gehr (3/21) Jun 26 2012 I think the default behaviour should be the behaviour that is wanted in
Hello everybody! I am new to D, and I am working on a program that calculates the area and circumference of a circle. However, when I compile it and run it, it waits for the user to input the radius, but then it closes while displaying a bunch of stuff. I've tried several ways to get it to wait, but none of them work. Here's my latest code: //Written in the D programming language! (Which rocks by the way!) //Import the necessary modules import std.stdio; import std.math; import std.conv; import std.string; //Welcome the user int welcome() { writefln ("Welcome to the Circle Calculator!"); return 0; } //Ask for the radius float askradius() { char[] number; float radius; writefln ("What is the radius of your circle?\n"); stdin.readln(number); radius = to!float(number); //Put the radius into a variable return radius; } //Show the user the results void result() { writefln ("The area is:", area()); writefln ("The circumference is:", cir()); } //Wait void wait() { writefln ("Type A to continue!"); exittest(); } //Exit tester void exittest() { char[] a; stdin.readln(a); if (a == "A") { exit(); } else { wait(); } } //Loop escape void exit() { } //Define pi float pi() { float pi = 3.14159265358979323; return pi; } //Calculate the square of the radius (for the area) float sqradius() { float sqradius = askradius() * askradius(); return sqradius; } //Calculate area float area() { float area = pi() * sqradius(); return area; } //Calculate double the radius (for the circumference) float dbradius() { float dbradius = askradius() * 2; return dbradius; } //Calculate circumference float cir() { float cir = pi() * dbradius(); return cir; } void main() { welcome(); askradius(); dbradius(); sqradius(); area(); cir(); result(); wait(); } How should I fix this so it will wait for the user to press a key to exit? Thanks a ton! -Alexander
Jun 26 2012
By the way, this is just my 2nd program in D. It is just for fun, and I'm doing it to practice using this language. This is normally how I teach myself languages. I write a simple one then a more complex one on and on until I'm fluent in the language. I don't have the book (but I'll get it soon), and I've just tried to use online references for this so far. Thanks again!
Jun 26 2012
You should be able to just do a readln() before exiting to give the user a chance to read everything, and hit enter to exit.
Jun 26 2012
On Tuesday, 26 June 2012 at 14:53:33 UTC, Adam D. Ruppe wrote:You should be able to just do a readln() before exiting to give the user a chance to read everything, and hit enter to exit.I just tried that, and it still closed right after I typed the radius. It looks almost like error code that pops up, but it closes so fast there's no way I could possibly read it.
Jun 26 2012
On Tue, 26 Jun 2012 10:40:18 -0400, Alexander <alexander alexandermohn.com> wrote:Hello everybody! I am new to D, and I am working on a program that calculates the area and circumference of a circle. However, when I compile it and run it, it waits for the user to input the radius, but then it closes while displaying a bunch of stuff.I'm assuming you are running on Windows. Windows with console output will allocate a console, and destroy the console after the program is finished. If you want it to keep the console up, start the command line interpreter (cmd.exe) before-hand and then run the program from within the console. Then all the output stays put.//Wait void wait() { writefln ("Type A to continue!"); exittest(); } //Exit tester void exittest() { char[] a; stdin.readln(a); if (a == "A") { exit(); } else { wait(); } }Hm... interesting code here :) This is not horrible, just... weird. You probably want to avoid recursion in this case: void wait() { char[] a; while(a != "A") { writeln("Type A to continue!"); stdin.readln(a); } } -Steve
Jun 26 2012
On 06/26/2012 09:43 PM, Steven Schveighoffer wrote:On Tue, 26 Jun 2012 10:40:18 -0400, Alexander <alexander alexandermohn.com> wrote: ...It is functional style. ;)//Wait void wait() { writefln ("Type A to continue!"); exittest(); } //Exit tester void exittest() { char[] a; stdin.readln(a); if (a == "A") { exit(); } else { wait(); } }Hm... interesting code here :) This is not horrible, just... weird.You probably want to avoid recursion in this case: void wait() { char[] a; while(a != "A") { writeln("Type A to continue!"); stdin.readln(a); } } -SteveI want the two examples to generate comparable code.
Jun 26 2012
So, I've taken out the loop part that is "interesting" and replaced it with the readln() alternative. However, I'm still getting what looks like an error. I managed to take a screenshot of what pops up, and here is what it says: std.conv.ConvException C:\D\dmd2\windows\bin\..\..\src\phobos\std\conv.d(1597): Unexpected ' ' when converting from type char[] to type float ----------------- C:\D\dmd2\windows\bin\..\..\src\phobos\std\conv.d(1597): float std.conv.toImpl!(float, char[]).toImpl(char[]) C:\D\dmd2\windows\bin\..\..\src\phobos\std\conv.d(245): float std.conv.to!(float).to!(char[]).to(char[]) C:\Users\Alexander\Documents\D\circlecalc.d(23): float circlecalc.askradius() C:\Users\Alexander\Documents\D\circlecalc.d(80): _Dmain ----------------- Does anyone understand this error code? I believe it means that it isn't letting me convert the user input into a floating number in function askradius(). How do I fix this? (Just a note, the above part is popping up INSTEAD of what is supposed to pop up.) Thanks!
Jun 26 2012
I'll probably put in this alternative:void wait() { char[] a; while(a != "A") { writeln("Type A to continue!"); stdin.readln(a); }Thanks!
Jun 26 2012
On Tue, 26 Jun 2012 16:39:07 -0400, Alexander <alexander alexandermohn.com> wrote:So, I've taken out the loop part that is "interesting" and replaced it with the readln() alternative. However, I'm still getting what looks like an error. I managed to take a screenshot of what pops up, and here is what it says: std.conv.ConvException C:\D\dmd2\windows\bin\..\..\src\phobos\std\conv.d(1597): Unexpected ' ' when converting from type char[] to type float ----------------- C:\D\dmd2\windows\bin\..\..\src\phobos\std\conv.d(1597): float std.conv.toImpl!(float, char[]).toImpl(char[]) C:\D\dmd2\windows\bin\..\..\src\phobos\std\conv.d(245): float std.conv.to!(float).to!(char[]).to(char[]) C:\Users\Alexander\Documents\D\circlecalc.d(23): float circlecalc.askradius() C:\Users\Alexander\Documents\D\circlecalc.d(80): _Dmain ----------------- Does anyone understand this error code?Oh, readln includes the newline by default, so to!float is choking on that. Just remove the newline character: radius = to!float(strip(number)); (must import std.string) -Steve
Jun 26 2012
Steven Schveighoffer:Oh, readln includes the newline by default, so to!float is choking on that.Similar things happen often. But Andrei says this is good, because it's more orthogonal. As Sting, I don't subscribe to this point of view. Orthogonality isn't more important than practicality. Bye, bearophile
Jun 26 2012
On Tue, 26 Jun 2012 17:17:29 -0400, bearophile <bearophileHUGS lycos.com> wrote:Steven Schveighoffer:I agree with Andrei, there is no outlet for errors in the to!T function, exception is the logical choice. But I also agree with you that if you don't care, it should be possible to ignore the errors without the cumbersome try-catch mechanism. Something like: to!(float, throw.No)(a) or toNoThrow!float(a) -SteveOh, readln includes the newline by default, so to!float is choking on that.Similar things happen often. But Andrei says this is good, because it's more orthogonal. As Sting, I don't subscribe to this point of view. Orthogonality isn't more important than practicality.
Jun 26 2012
That must be why, I didn't import std.string! Thanks!
Jun 26 2012
Steven Schveighoffer:I agree with Andrei, there is no outlet for errors in the to!T function, exception is the logical choice.Maybe I was not clear enough, so let me explain a bit better. What I don't like is to!int("15\n") to be seen as an error in the first place. I'd like it to ignore leading and trailing whitespace, as in Python (stripping it automatically):15 So it's not a matter of ignoring the errors, but ignoring that leading and trailing whitespace. On the other hand, if you write to!dstring("15\n") this shouldn't strip away whitespace :-) So I understand Andrei motives too. To do that you have to hard-code different behaviors inside to!() according to the destination type. This is not so good.int("15\n")But I also agree with you that if you don't care, it should be possible to ignore the errors without the cumbersome try-catch mechanism. Something like: to!(float, throw.No)(a) or toNoThrow!float(a)What is it doing if you give it a wrong input string 'a'? This seems useful, but as you have seen it's different from what I was looking for. A non-throwing to!() may be handy to have: nullableTo!int("XX") => empty Nullable Nullable.get() is able to throw an exception. If you handle both empty and full cases of a nullable the D compiler is not able to statically infer that your code can't throw. You have to wrap that code into catching instructions any way, if you want your whole function (that uses nullableTo) to be nonthrow. Bye, bearophile
Jun 26 2012
On Tue, 26 Jun 2012 19:10:25 -0400, bearophile <bearophileHUGS lycos.com> wrote:Steven Schveighoffer:Right, but what if it's an error in your code if whitespace is present? Then you have to check for whitespace and throw your own error. I admit, that would likely be a rare occasion. But having both behaviors should be possible.I agree with Andrei, there is no outlet for errors in the to!T function, exception is the logical choice.Maybe I was not clear enough, so let me explain a bit better. What I don't like is to!int("15\n") to be seen as an error in the first place. I'd like it to ignore leading and trailing whitespace, as in Python (stripping it automatically):Options should be possible. I think probably we could even accept them like so: T to(T, U, Opts...)(U u, Opts opts) if(makesSenseAsToOpts!(T, U, Opts)) { ... } Then define options such as: enum TrimWhitespace : bool { Yes = true, No = false }15 So it's not a matter of ignoring the errors, but ignoring that leading and trailing whitespace. On the other hand, if you write to!dstring("15\n") this shouldn't strip away whitespace :-) So I understand Andrei motives too. To do that you have to hard-code different behaviors inside to!() according to the destination type. This is not so good.int("15\n")0. Similar to atoi That is, it consumes all leading numeric characters, and ignores the rest. I realize in hindsight this is no good for ignoring leading whitespace. Probably an option to ignore whitespace is better.But I also agree with you that if you don't care, it should be possible to ignore the errors without the cumbersome try-catch mechanism. Something like: to!(float, throw.No)(a) or toNoThrow!float(a)What is it doing if you give it a wrong input string 'a'?This seems useful, but as you have seen it's different from what I was looking for. A non-throwing to!() may be handy to have: nullableTo!int("XX") => empty Nullable Nullable.get() is able to throw an exception. If you handle both empty and full cases of a nullable the D compiler is not able to statically infer that your code can't throw. You have to wrap that code into catching instructions any way, if you want your whole function (that uses nullableTo) to be nonthrow.This might be a good option too, but couldn't we just do: to!(Nullable!int)("XX") Many possibilities exist. -Steve
Jun 26 2012
On Jun 26, 2012, at 4:40 PM, Steven Schveighoffer wrote:On Tue, 26 Jun 2012 19:10:25 -0400, bearophile =<bearophileHUGS lycos.com> wrote:=20function, exception is the logical choice.Steven Schveighoffer: =20I agree with Andrei, there is no outlet for errors in the to!T =first place.=20 Maybe I was not clear enough, so let me explain a bit better. =20 What I don't like is to!int("15\n") to be seen as an error in the =(stripping it automatically):I'd like it to ignore leading and trailing whitespace, as in Python ==20 Right, but what if it's an error in your code if whitespace is =present? Then you have to check for whitespace and throw your own = error. to!int(trim("5\n")) no?=
Jun 26 2012
On Tue, 26 Jun 2012 19:44:34 -0400, Sean Kelly <sean invisibleduck.org> wrote:On Jun 26, 2012, at 4:40 PM, Steven Schveighoffer wrote:That was my original suggestion. It fixes the problem, but can seem quite unintuitive to a developer that they have to do this. Plus if it actually *is* an error for the string to have whitespace, you would want it to throw. My point to bearophile is, we may want both options. I can easily see someone using just to!int(userInput), and testing without ever putting in spaces, and then user does and the application blows up (quite needlessly). -SteveOn Tue, 26 Jun 2012 19:10:25 -0400, bearophile <bearophileHUGS lycos.com> wrote:to!int(trim("5\n")) no?Steven Schveighoffer:Right, but what if it's an error in your code if whitespace is present? Then you have to check for whitespace and throw your own error.I agree with Andrei, there is no outlet for errors in the to!T function, exception is the logical choice.Maybe I was not clear enough, so let me explain a bit better. What I don't like is to!int("15\n") to be seen as an error in the first place. I'd like it to ignore leading and trailing whitespace, as in Python (stripping it automatically):
Jun 26 2012
On 06/27/2012 01:40 AM, Steven Schveighoffer wrote:On Tue, 26 Jun 2012 19:10:25 -0400, bearophile <bearophileHUGS lycos.com> wrote:I think the default behaviour should be the behaviour that is wanted in the majority of cases.Steven Schveighoffer:Right, but what if it's an error in your code if whitespace is present? Then you have to check for whitespace and throw your own error. I admit, that would likely be a rare occasion. But having both behaviors should be possible. ...I agree with Andrei, there is no outlet for errors in the to!T function, exception is the logical choice.Maybe I was not clear enough, so let me explain a bit better. What I don't like is to!int("15\n") to be seen as an error in the first place. I'd like it to ignore leading and trailing whitespace, as in Python (stripping it automatically):
Jun 26 2012