Difficulty performing actions in a finite loop with user input - loops

I'm using Allegro CL Express on a Mac and I'm not sure if the program is having difficulties, or my code is poorly formed. I'm trying to take 4 user input integers and then add them after the last value is entered
Desired outcome:
(stuff)
Enter a number: 4
Enter a number: 3
Enter a number: 2
Enter a number: 1
10
Here's what I currently have:
(defun stuff ()
(loop repeat 4
sum (format t "Enter a number: ")
(parse-integer (read-line))))
EDIT:
After some great help, here is what I have:
CG-USER(18): (defun stuff ()
(loop repeat 4
sum (progn
(format t "Enter a number: ")
(parse-integer (read-line)))))
STUFF
CG-USER(19): (stuff)
Enter a number: 1
It just hangs after I enter an integer and press return.

Using a compiler helps. Look what SBCL says when evaluating your form:
CL-USER> (defun stuff ()
(loop repeat 4
sum
(format t "Enter a number: ")
(parse-integer (read-line))))
; in: DEFUN STUFF
; (LOOP REPEAT 4
; SUM (FORMAT T "Enter a number: ") (PARSE-INTEGER (READ-LINE)))
;
; caught ERROR:
; during macroexpansion of (LOOP REPEAT 4 ...). Use *BREAK-ON-SIGNALS* to
; intercept.
;
; (PARSE-INTEGER
; (READ-LINE)) found where a LOOP keyword or LOOP type keyword expected
; current LOOP context: SUM (FORMAT T "Enter a number: ") (PARSE-INTEGER
; (READ-LINE)).
;
; compilation unit finished
; caught 1 ERROR condition
STUFF
The most important part there is
; (PARSE-INTEGER
; (READ-LINE)) found where a LOOP keyword or LOOP type keyword expected
; current LOOP context: SUM (FORMAT T "Enter a number: ") (PARSE-INTEGER
; (READ-LINE)).
So it's getting (PARSE-INTEGER (READ-LINE)) where a loop keyword or type is expected. Why's that? The documentation for loop should tell us. sum is a numeric accumulation:
numeric-accumulation::= { count | counting | sum |
summing | maximize | maximizing |
minimize | minimizing }
{form | it}
[into simple-var] [type-spec]
So, after sum, there should be a single form. You'd just need to wrap your prompt and the call to read-line in, e.g., a progn to produce a single form:
(defun stuff ()
(loop repeat 4
sum (progn
(format *query-io* "Enter a number: ")
(parse-integer (read-line *query-io*)))))
Note also that I used the stream *query-io* for input and output. You don't have to do that, but it's probably a bit more robust, since:
The value of *query-io*, called query I/O, is a bidirectional stream
to be used when asking questions of the user. The question should be
output to this stream, and the answer read from it.

Related

Haskell: looping over user input gracefully

This is an example from Learn You a Haskell:
main = do
putStrLn "hello, what's your name?"
name <- getLine
putStrLn ("Hey, " ++ name ++ ", you rock!")
The same redone without do for clarity:
main =
putStrLn "hello, what's your name?" >>
getLine >>= \name ->
putStrLn $ "Hey, " ++ name ++ ", you rock!"
How am I supposed to loop it cleanly (until "q"), the Haskell way (use of do discouraged)?
I borrowed this from Haskell - loop over user input
main = mapM_ process . takeWhile (/= "q") . lines =<< getLine
where process line = do
putStrLn line
for starters, but it won't loop.
You can call main again and check if your string is "q" or not.
import Control.Monad
main :: IO ()
main =
putStrLn "hello, what's your name?" >>
getLine >>= \name ->
when (name /= "q") $ (putStrLn $ "Hey, " ++ name ++ ", you rock!") >> main
λ> main
hello, what's your name?
Mukesh Tiwari
Hey, Mukesh Tiwari, you rock!
hello, what's your name?
Alexey Orlov
Hey, Alexey Orlov, you rock!
hello, what's your name?
q
λ>
May be you can also use laziness on IO type by adapting the System.IO.Lazy package. It basically includes only run :: T a -> IO a and interleave :: IO a -> T a functions to convert IO actions into lazy ones back and forth.
import qualified System.IO.Lazy as LIO
getLineUntil :: String -> IO [String]
getLineUntil s = LIO.run ((sequence . repeat $ LIO.interleave getLine) >>= return . takeWhile (/=s))
printData :: IO [String] -> IO ()
printData d = d >>= print . sum . map (read :: String -> Int)
*Main> printData $ getLineUntil "q"
1
2
3
4
5
6
7
8
9
q
45
In the above code we construct an infinite list of lazy getLines by repeat $ LIO.interleave getLine of type [T String] and by sequence we turn it into T [String] type and proceed reading up until "q" is received. The printData utility function is summing up and printing the entered integers.

Why this for loop starts from half and not prints out every thing?

I am learning C , I have written one C program which asks the user to enter a starting number and ending number , and it prints out the number stating from starting number to ending number . For example , if a user enters 5 as the starting number and 10 as the ending number , it prints out 5 6 7 8 9 10 . Here is the code : -
#include <stdio.h>
#include <stdlib.h>
int main()
{
int start ;
int end ;
int counter ;
// Asking the starting number
printf("Enter the starting number : ") ;
scanf("%d" , &start) ;
// Asking the last number
printf("Enter the last number : ") ;
scanf("%d" , &end) ;
for (counter = start ; counter <= end ; counter++)
{
printf("%d\n" , counter) ;
}
return 0;
}
The above code runs perfectly for small gap numbers (like 5 to 10 , 1000 to 1025) , But whenever I type the large gap numbers like 100 to 500 , It prints out the numbers starting from 205 to 500 , Even I scroll up I can't find the numbers from 100 to 204 . I am using Code::Blocks (version 13.12) . Can anybody figure it out whats wrong with this code ? Thanks :)
Command line display has a limited history. You are printing a large amount of numbers old lines get removed.
Print you numbers into a file using fopen() and fprintf(), so you can inspect them all.
As everybody has mentioned, your command line history has run out of its limit and hence, you cannot scroll back to the starting point. So, you're missing out the complete output.
Assuming you're on linux, run your executable like
./a.out > test1.txt
and then open and check the newly created file using vi
vim test1.txt
Hope you'll get the complete o/p.
You can make it a bit easier on yourself by printing the numbers out in sequence without newlines to confirm. That will eliminate the scrolling issue:
for (counter = start ; counter <= end ; counter++)
{
printf(" %d" , counter) ;
}
printf ("\n");
Try adding a space in your printf() instead of newline character '\n' like
printf("%d " , counter) ;
Your program will print the whole sequence, just that you are not able to see it.
Try writing the output in a file and then you will be able to see the whole output.
This thing is happening because console has a limited capacity, otherwise your code will run perfectly fine.

Game Loop for Racket

I am working on a very basic memory game in RACKET that presents the user with 7 random numbers from 1 to 10 and asks them to type in the numbers in the same order. I can get this to work once but I want it to continually run until the user exits out. (Repeat MAIN PROGRAM) Any ideas on how to accomplish this???
(require math/base)
; =======================================
; Functions
; =======================================
; set essentially constants
(define lowerLimit 1)
(define upperLimit 11)
(define amount 7)
; builds a list with random integers between lowerLimit and upperLimit
(define (buildSimon x L)
(cond [(= x 0) L]
[else (buildSimon (- x 1) (cons (random-integer lowerLimit upperLimit) L))]))
; adds element to back of the list
(define (addBack L e)
(if (null? L)
(list e)
(cons (first L) (addBack (rest L) e))))
; gets input from user and builds list
(define (getInput n x L)
(cond [(= n 1) (addBack L x)]
[else (getInput (- n 1) (read) (addBack L x))]))
; =======================================
; Main program below here
; =======================================
; Generate new random number sequence
(printf "Simon says: ")
(define sequence (buildSimon amount (list)))
(display sequence) (newline)
(printf "== Memorize and guess ==\n")
(printf "== Type 'go' and hit enter to guess ==\n")
(read)
; Add spacing to hide numbers
(printf "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
(printf "== Type the numbers in order as they appeared. ==\n")
(printf "== Hit ENTER in between each number. ==\n")
; Gather input for comparison
(define answer (getInput amount (read) (list)))
; Do comparison
(if (equal? sequence answer)
(printf "Correct! Congratulations on your perfect memory.\n")
(printf "Wrong! I'm sorry your memory has failed you.\n"))
Thank you in advance.
You can create a function which contains all of your main code, with the last line of the function recursively calling itself.

Using random library to guess number (Python)

#This program generates random number
#user enters guess
#progam tells user higher, lower or correct based on user input.
import random
def main():
# Get a random number.
number = random.randint(1, 101)
user_guess = int(input("Pick a number between 1 and 100: "))
userguess = guess(user_guess, number)
print(userguess)
def guess(num1, num2):
if num1 > num2:
return("Lower")
elif num1 < num2:
return("Higher")
else:
return("Correct")
main()
I can get the program to generate a random number, then display higher or lower, but not as again. It is supposed to ask again until it hits the random and then displays 'correct'
You need a loop to keep prompting until the correct answer is guessed, while(True) keeps going until a break; is reached. Try something like this.
def guess(num):
while(True):
user_guess = int(input("Pick a number between 1 and 100: "))
if user_guess > num:
print("Lower\n")
elif user_guess < num:
print("Higher\n")
else:
print("Correct")
break;
This will repeatedly ask user for numbers untill they are correct replace your main method with the following
def main():
# Get a random number.
number = random.randint(1, 101)
guess(number)
Edit: replaced true with True

Getting Sytax error using the While Loop in Python 3.3.2

Here is my code:
import random
secret = random.randint (1, 99)
guess = 0
tries = 0
print ("Ahoy! I'm the Dread Pirate Roberts, and I have a secret!")
print ("It is a number from 1 to 99. I'll give you 6 tries. "
while tries < 6 and guess != secret:
guess = input ("What's yer guess? ")
if guess < secret:
print ("Too low, ye scurvy dog!")
elif guess > secret:
print ("Too High, landlubber!")
tries = tries + 1
if (guess == secret):
print ("AVAST! Ye got it! Found my secret, ye did it!"
else:
print ("No more guesses! Better luck next time, matey!)
print ("The secret number was"), secret
For some reason I am getting an invalid syntax on "while". I cannot seem to find out why as this used work for some reason.
You're missing a closing parenthesis at the end of this line:
print ("It is a number from 1 to 99. I'll give you 6 tries. "
^
This line isn't indented properly:
while tries < 6 and guess != secret:
guess = input ("What's yer guess? ")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
guess will be a string, so you should convert it into an integer before treating it like one:
guess = int(input("What's yer guess? "))
Finally, this line is missing a closing double quote:
print ("No more guesses! Better luck next time, matey! )
^

Resources