Why program flow control executes randomly - haskell

I'm trying to learn math and Haskell at the same time by programming a simple math learning program.
It starts by:
Generating random numbers.
Filters those numbers to create an easy problem to work with.
Display the question then take my answer
Lastly, it hands both my answer and the correct answer to another function to give me feedback (a "Congratulations" --or-- "Sorry, the correct answer is BLANK).
For some reason, after the congratulations function ends, it seems to randomly choose where it goes next, either:
It returns to main (which is what I expect it to do).
Or at random loops it'll go immediately to the math testing function. When this happens, step 2 from above doesn't occur and I start getting fractional numbers in the question. Then it may repeat this step or go back to main.
When trying to debug the problem I would just keep hitting RETURN and it would occur at different times. I've also added some debug 'print' statements.
Here's 3 functions from the program. Note that main calls funPercentOfNumberToAnother:
funPercentOfNumberToAnother :: IO ()
funPercentOfNumberToAnother = do
(percentDec, percentStr) <- getPercent
ofNum <- getDecimal (200 :: Decimal)
let isNum = percentDec * ofNum
if uglyAnswers ([ofNum, isNum], [percentDec])
then do
putStrLn ("ofNum: " ++ show ofNum)
putStrLn ("isNum: " ++ show isNum)
putStrLn "___________________________"
funPercentOfNumberToAnother
else do
putStrLn ("ofNum: " ++ show ofNum)
putStrLn ("isNum: " ++ show isNum)
putStrLn "Percents"
-- putStrLn "\n\n"
putStrLn (show isNum ++ " is what percent of " ++ show ofNum ++ "?\n" )
putStr "> "
ans <- getLine
submitStringAnswer (ans, percentStr ++ "%")
submitStringAnswer :: (String, String) -> IO ()
submitStringAnswer (myAns, correctAns) = do
if myAns == correctAns
then putStrLn "Congratz!"
else do
putStrLn ("Sorry the correct answer is: " ++ show correctAns)
pause
pause :: IO ()
pause = do
x <- getLine
putStrLn ""
Here's my debug output. Notice that The only time it gives fractional numbers is after it doesn't return to main immediately after pause ends.
__ __ _ _ _ _
| \/ | __ _| |_| |__ ___ _ __ ___ __ _| |_(_) ___ ___
| |\/| |/ _` | __| '_ \ / _ \ '_ ` _ \ / _` | __| |/ __/ __|
| | | | (_| | |_| | | | __/ | | | | | (_| | |_| | (__\__
|_| |_|\__,_|\__|_| |_|\___|_| |_| |_|\__,_|\__|_|\___|___/
1.) Learn Math
2.) Math Lookup
3.) Quit Excolo
1
ofNum: 35
isNum: 15.75
___________________________
ofNum: 120
isNum: 102
Percents
102 is what percent of 120?
>
Sorry the correct answer is: "85%"
15.75 is what percent of 35?
>
Sorry the correct answer is: "45%"
__ __ _ _ _ _
| \/ | __ _| |_| |__ ___ _ __ ___ __ _| |_(_) ___ ___
| |\/| |/ _` | __| '_ \ / _ \ '_ ` _ \ / _` | __| |/ __/ __|
| | | | (_| | |_| | | | __/ | | | | | (_| | |_| | (__\__
|_| |_|\__,_|\__|_| |_|\___|_| |_| |_|\__,_|\__|_|\___|___/
1.) Learn Math
2.) Math Lookup
3.) Quit Excolo
1
ofNum: 80
isNum: 44
Percents
44 is what percent of 80?
>
Sorry the correct answer is: "55%"
__ __ _ _ _ _
| \/ | __ _| |_| |__ ___ _ __ ___ __ _| |_(_) ___ ___
| |\/| |/ _` | __| '_ \ / _ \ '_ ` _ \ / _` | __| |/ __/ __|
| | | | (_| | |_| | | | __/ | | | | | (_| | |_| | (__\__
|_| |_|\__,_|\__|_| |_|\___|_| |_| |_|\__,_|\__|_|\___|___/
1.) Learn Math
2.) Math Lookup
3.) Quit Excolo
1
ofNum: 15
isNum: 2.25
___________________________
ofNum: 60
isNum: 0.6
___________________________
ofNum: 40
isNum: 30
Percents
30 is what percent of 40?
>
Sorry the correct answer is: "75%"
0.6 is what percent of 60?
>
Sorry the correct answer is: "1%"
2.25 is what percent of 15?
>
Sorry the correct answer is: "15%"
If it helps, the only thing that is remotely relevant that I've found so far is: Second of several forked processes does not run in Haskell
.
Lastly, I'm right at the entry level of Monads if that helps formulate your answer.
I would appreciate any help anyone can give as to what's happening, id est, why it's not returning straight to main after pause ends, and why would it skip the fractional number filter.
Thanks ^^

In funPercentOfNumberToAnother, you have this clause:
if uglyAnswers ([ofNum, isNum], [percentDec])
then do
putStrLn ("ofNum: " ++ show ofNum)
putStrLn ("isNum: " ++ show isNum)
putStrLn "___________________________"
funPercentOfNumberToAnother
else do
putStrLn ("ofNum: " ++ show ofNum)
putStrLn ("isNum: " ++ show isNum)
putStrLn "Percents"
Your intent is to go back to the beginning of the function and start over, if the numbers are ugly; or otherwise continue with showing the numbers to the user. That works as far as it goes, but ask yourself...what happens at the end of this if clause? The stuff that is not in either the then or else branch is executed regardless, once either the then or else is done executing.
So, when you get some ugly numbers, you start a recursive call that looks for better numbers and displays them. Then when that recursive call is finished, you go on to show the user the original, ugly numbers anyway!
You will need a different control flow here, such as writing a function that always returns a non-ugly number, and then just using that in your (now non-recursive) funPercentOfNumberToAnother function. Or you could pull the rest of the function's body, the part that shows the numbers to the user, into the else part of the if, so that you don't do it for numbers that are ugly.

As per amalloy's great explanation I understood what was happening and fixed, then tested the issue. Having code outside the if statement of:
if uglyAnswers
then funPercentOfNumberToAnother
else ...
caused the bad answers to later make their way down when the recursion stopped. So essentially I was stocking up on them.
Maybe this can explain it better. See that I got a clean answer on the first try so it didn't have to go through the recursion. For the second go there were two calls because the first call found a fractional answer:
__ __ _ _ _ _
| \/ | __ _| |_| |__ ___ _ __ ___ __ _| |_(_) ___ ___
| |\/| |/ _` | __| '_ \ / _ \ '_ ` _ \ / _` | __| |/ __/ __|
| | | | (_| | |_| | | | __/ | | | | | (_| | |_| | (__\__
|_| |_|\__,_|\__|_| |_|\___|_| |_| |_|\__,_|\__|_|\___|___/
1.) Learn Math
2.) Math Lookup
3.) Quit Excolo
1
In the else statement
===================================
Finally outside the else statement
ofNum: 10
isNum: 4
__ __ _ _ _ _
| \/ | __ _| |_| |__ ___ _ __ ___ __ _| |_(_) ___ ___
| |\/| |/ _` | __| '_ \ / _ \ '_ ` _ \ / _` | __| |/ __/ __|
| | | | (_| | |_| | | | __/ | | | | | (_| | |_| | (__\__
|_| |_|\__,_|\__|_| |_|\___|_| |_| |_|\__,_|\__|_|\___|___/
1.) Learn Math
2.) Math Lookup
3.) Quit Excolo
1
Bad answer alert!
===================================
In the else statement
===================================
Finally outside the else statement
ofNum: 160
isNum: 80
===================================
Finally outside the else statement
ofNum: 55
isNum: 0.55
Here's the workable code snippets from the original question:
funPercentOfNumberToAnother :: IO ()
funPercentOfNumberToAnother = do
(percentDec, percentStr) <- getPercent
ofNum <- getDecimal (200 :: Decimal)
let isNum = percentDec * ofNum
if uglyAnswers ([ofNum, isNum], [percentDec])
then funPercentOfNumberToAnother
else do
let message = show isNum ++ " is what percent of " ++ show ofNum ++ "?\n"
testProblem (percentStr ++ "%", message)
testProblem :: (String, String) -> IO ()
testProblem (correctAns, message) = do
putStrLn message
putStrLn "\n\n"
putStr "> "
myAns <- getLine
if myAns == correctAns
then putStrLn "Congratz!"
else do
putStrLn ("Sorry the correct answer is: " ++ show correctAns)
pause

Related

Cannot Create BuildFire Plugin With Angular

Githubs password authentication was removed. See the console below:
me#me-MBP BuildFireSDK % buildfire plugin init NixCodeAngular angular
______ _ _ _______ _
| ___ \ (_) | | | ___(_)
| |_/ /_ _ _| | __| | |_ _ _ __ ___
| ___ \ | | | | |/ _` | _| | | '__/ _ \
| |_/ / |_| | | | (_| | | | | | | __/
\____/ \__,_|_|_|\__,_\_| |_|_| \___|
Creating Plugin NixCodeAngular with tempalte angular
Username for 'https://github.com': myemail#gmail.com
Password for 'https://myemail#github.com':
Cloning into '/Users/me/Development/admins/nixcode-buildfire-2/BuildFireSDK/plugins/NixCodeAngular'...
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/BuildFire/angularPluginTemplate.git/'
Error: Cloning into '/Users/me/Development/admins/nixcode-buildfire-2/BuildFireSDK/plugins/NixCodeAngular'...
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/BuildFire/angularPluginTemplate.git/'
at toError (/opt/homebrew/lib/node_modules/buildfire-cli/node_modules/simple-git/promise.js:90:14)
at /opt/homebrew/lib/node_modules/buildfire-cli/node_modules/simple-git/promise.js:61:36
at Git.<anonymous> (/opt/homebrew/lib/node_modules/buildfire-cli/node_modules/simple-git/src/git.js:214:18)
at Git.fail (/opt/homebrew/lib/node_modules/buildfire-cli/node_modules/simple-git/src/git.js:1475:18)
at fail (/opt/homebrew/lib/node_modules/buildfire-cli/node_modules/simple-git/src/git.js:1433:20)
at /opt/homebrew/lib/node_modules/buildfire-cli/node_modules/simple-git/src/git.js:1442:16
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
You need to use a personal token for the password field, check here for more info and here on how to create it.

Jmeter executing scripts but provides blank report

I am running jmeter in non GUI mode in my linux server inside docker. When I check jmeter is installed or not it says its there with the version but when I execute my script it says as follows-
root#xxxxxxx:/# /var/xxxxx/apache-jmeter-5.1/bin/jmeter -n -t /lib/xxx/deduction.jmx -l test.jtl
Creating summariser <summary>
Created the tree successfully using /lib/xxx.s/deduction.jmx
Starting the test # Tue May 14 05:54:53 UTC 2019 (1557813293320)
Waiting for possible Shutdown/StopTestNow/HeapDump/ThreadDump message on port 4445
summary = 0 in 00:00:00 = ******/s Avg: 0 Min: 9223372036854775807 Max: -9223372036854775808 Err: 0 (0.00%)
Tidying up ... # Tue May 14 05:55:53 UTC 2019 (1557813353945)
... end of run
The same file works fine in my windows machine.
root#xxxxxx:/# /var/xxxxxx/apache-jmeter-5.1/bin/jmeter -v
_ ____ _ ____ _ _ _____ _ __ __ _____ _____ _____ ____
/ \ | _ \ / \ / ___| | | | ____| | | \/ | ____|_ _| ____| _ \
/ _ \ | |_) / _ \| | | |_| | _| _ | | |\/| | _| | | | _| | |_) |
/ ___ \| __/ ___ \ |___| _ | |___ | |_| | | | | |___ | | | |___| _ <
/_/ \_\_| /_/ \_\____|_| |_|_____| \___/|_| |_|_____| |_| |_____|_| \_\ 5.1 r1853635
Copyright (c) 1999-2019 The Apache Software Foundation
I experienced that also. In my case, the problem was the path set on JMeter component “CSV Data Set Config”. When I executed the project at my machine, the Jmeter searched and found the path, but after upload to the server I forgot to change the CSV path according to the server environment. After change it the tests were executed Ok on server. So, check if there is something like that on your JMeter project.

Issuse with recursion and the "input()" function in python 3.6

I am having a problem, I have function that takes input and returns True if the input is "yes", False if it is "no", and calls its self if the input is something else. Here is my code:
def call_from_Zeus():
system("cls||clear")
call_from_Zeus_string = """ ___ _ _ ___ ___ __ __ ___ _ _ ___ ___ _ _ _
|_ _| \| |/ __/ _ \| \/ |_ _| \| |/ __| / __| /_\ | | | |
| || .` | (_| (_) | |\/| || || .` | (_ | | (__ / _ \| |__| |__
|___|_|\_|\___\___/|_| |_|___|_|\_|\___| \___/_/ \_\____|____|
\33[1;37;49mFROM: \33[1;34;49mMr.Zeus[ADMIN\33[1;33;49m+\33[1;34;49m]\33[0m
\33[1;37;49mTO: USER#8009395797394869
\33[0m
"""
print(call_from_Zeus_string)
in1 = input('\t Accept Call(Enter "yes" or "no")? ')
if in1 == "yes" or in1 == "Yes" or in1 == "YES" or in1 == "y":
return True
elif in1 == "no" or in1 == "No" or in1 == "NO" or in1 == "n":
return False
else:
del in1
call_from_Zeus()
The code its self does not crash, but if the input is invalid it calls its self no matter what you enter it resorts to the else: statement.
I have no idea what is going on. As you can see I even tried deling the in1 variable. Thanks for any help in advance!
-Zeus

Strange bug in Julia or Screen

On Debian 8 Linux, I use vim together with screen to send lines from vim to a julia session. Today, I tried https://github.com/Keno/Cxx.jl. I followed the instructions there (i.e. I compiled the latest version 0.5.0-dev+3609 of Julia). The following bug appeared when I tried example 1, I could pinpoint it to the following simple steps:
Create the following files (don't overwrite your own files):
printf "using Cxx\ncxx\"\"\"#include<iostream> \"\"\"\ncxx\"\"\"void testfunction(){std::cout<<\"worked\"<< std::endl;}\"\"\"\njulia_function() = #cxx testfunction()\n" > start
and printf "julia_function()\n" > freeze
Open terminal 1 (I use gnome-terminal) and write screen -S session and then start Julia with julia. It should look like
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: http://docs.julialang.org
_ _ _| |_ __ _ | Type "?help" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.5.0-dev+3609 (2016-04-18 07:07 UTC)
_/ |\__'_|_|_|\__'_| | Commit a136a6e (0 days old master)
|__/ | x86_64-linux-gnu
julia>
Open terminal 2 and do
screen -S session -p 0 -X eval "readreg p start" "paste p" Terminal 1 should now look like
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: http://docs.julialang.org
_ _ _| |_ __ _ | Type "?help" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.5.0-dev+3609 (2016-04-18 07:07 UTC)
_/ |\__'_|_|_|\__'_| | Commit a136a6e (0 days old master)
|__/ | x86_64-linux-gnu
julia> using Cxx
julia> cxx"""#include&ltiostream&gt """
true
julia> cxx"""void testfunction(){std::cout<&lt"worked"&lt&lt std::endl;}"""
true
julia> julia_function() = #cxx testfunction()
julia_function (generic function with 1 method)
julia>
Now the strange bug appears: writing "ju", using TAB to complete to "julia_function" and adding "()" by hand in terminal 1 leads to
julia> julia_function()
worked
julia>
But if I do steps 1, 2, 3 and then screen -S session -p 0 -X eval "readreg p freeze" "paste p" in terminal 2 or write julia_function() in terminal 1 without using TAB to complete then I get a freeze in terminal 1:
julia> julia_function()
If I do steps 1, 2, 3, use TAB completion as described above, then (i.e. after the first call, which compiles the function) screen -S session -p 0 -X eval "readreg p freeze" "paste p" in terminal 2 and julia_function() without using TAB in terminal 1 work as expected (it prints "worked") and don't cause a freeze.
If I do not use screen at all, it works (with and without TAB). Can you please tell me what is going on here?

How does this zipfile print a message to my console when it's unzipped?

I downloaded a font from FontSpace.com
and unzipped it using unzip my_font.zip
The following was then printed:
Archive: kimberly-geswein_just-realize.zip
_____ _ ____
| ___|__ _ __ | |_/ ___| _ __ __ _ ___ ___
| |_ / _ \| '_ \| __\___ \| '_ \ / _` |/ __/ _ \
| _| (_) | | | | |_ ___) | |_) | (_| | (_| __/
|_| \___/|_| |_|\__|____/| .__/ \__,_|\___\___|.com
|_|
Visit us at http://www.fontspace.com for more
information on this font, or for thousands of
more fonts!
inflating: JustRealize.ttf
inflating: JustRealizeBold.ttf
extracting: KGFonts-TOU.txt
How was this achieved? I don't mean the unzipping, I mean the printing of the advertisement.
On the command line you can do this with command zipnote which generally comes with the zip command.
From the manpage:
Example:
zipnote foo.zip > foo.tmp
ed foo.tmp
... then you edit the comments, save, and exit ...
zipnote -w foo.zip < foo.tmp
The trick is to put the "comment" at the end of that .tmp file that is read back into the .zip by the zipnote command.

Resources