Difference between random.randint and random.sample - random

I have read the documentation for each and find it a bit hard to comprehend the differences here. I wrote this code using random.sample:
import random
print "Welcome to the guessing game."
number_of_guesses = 1
correct_number = random.sample(range(1,101),1)
while number_of_guesses < 999:
user_choice = int(input("Guess a number between 1 and 100: "))
if user_choice == correct_number:
print "You guessed the number in %s tries." % number_of_guesses
elif user_choice < correct_number:
print "Too low, guess again."
number_of_guesses += 1
elif user_choice > correct_number:
print "Too high, guess again."
number_of_guesses += 1
When i run this code and enter a number i get "Too low, guess again." regardless of what number I enter, yet when i use random.randomint it works correctly. Can anyone explain why this happens?

random.sample(range(1,101),1) will return a singleton list containing an integer, whereas random.randint(1,100) will directly return the integer itself. Note that random.randint is an inclusive bound (i.e. it can return either of the endpoints)
You could also use random.choice(range(1, 101)) to get the integer. In any case, I'd assume that randint is the fastest option.

Related

Python activity

I am attempting to use a program in Geany which is designed to tell me whether a number is even or odd. Here is the program I have written.
def activity01(num1):
'''Determine if an input number is Even or Odd'''
if [num1 % 2 == 0]
return 'even'
else:
return 'odd'
Can anyone tell me what is wrong with this program? It is telling me right now that line 3 has invalid syntax at the end. I am running the program in a test environment from the class I got the activity through.
Put a colon after if (num1 % 2 == 0). You should be able to use the code below for your function:
def activity01(num1):
"""Determine if an input number is Even or Odd"""
if num1 % 2 == 0:
return "even"
else:
return "odd"
print activity01(3)
print activity01(4)

Printing in while loop, clearing previous iteration prints

I have the following code:
print("Hi there!")
def inputyournumber():
while True:
num = input("your number is?:")
if int(num) <100:
break
return
The output is:
Hi there!
your number is?: 101
your number is?: 1002
your number is?: 100
your number is?: 99
i just want the initial prints: and the final output until a correct input is entered:
Hi there!
your number is?: 99
Erasing the initially wrong inputs, but keeping the prints prior the loop. Is it possible? Or do i have to reprint them? My issue in just clearing everything then reprint the prior texts together with the correct input is that it may consume more time for more complex part of the code with similar problem.
Do you mean it only print out the number you entered when the number you enter is 100?
First, the input you get, will be a string, so the comparison won't work.
maybe this is what you wanted?
def printnum():
while True:
print('Hi there!')
num = input("your number is: ")
if num != '100':
continue
break
print(num)
printnum()

Syntax error on else in my quiz

I'm new to a program called Pythonista. I'm doing a quiz and when I try to test it I get a syntax error.
Here is the error:
Your else indentation is not proper at line number 10
your code with proper indentation:
def quiz():
score = 0
begin = raw_input("do you want to start ?")
if begin == "yes":
print "A : 56"
print "B : 48"
print "C : 45"
q1 = raw_input("what is 12*4")
if q1 in ["b","B"]:
print "congrats !! well done!1"
score += 1
else:
print "sorry!! you are wrong try next one !! good luck"
print "A : Another ice age"
print "B : A meteor will hit the earth"
print "C : Aliens will invade earth"
q2 = raw_input("what will happen in 50 years?")
if q2 in ["a","A"]:
print "nice !! keep going!1"
score += 1
else:
print "sorry!! you are wrong try next one !! good luck"
return score
else:
print "ok bye"
return 0
This is just an edit on top of your code. But I won't suggest this approach as you are writing same code for both question again and again.Instead of that I will suggest to use one proper data structure and loop through that then it will be dynamic enough to do more quiz.You can use one array of dictionary like this-
[{"question":"what is 5*4 ?","options":[10,20,30],"answer_index":1},{"question":"what is 10*4 ?","options":[40,50,60,30],"answer_index":0}]
I'm not familiar with Pythonista, but, from a quick search, it uses significant white-space. In which case, your else is indented when it should be at the same level as its corresponding if. There are further errors like this later on.
See here for more details: http://omz-software.com/pythonista/docs/tutorial/controlflow.html

Infinite Loop x Counter Problems

Hello I have three problems with my code:
when I type in "N" for my first question, it goes into an error.
I get in an infinite loop after the "Run again?" input.
my counters do not add up properly so even when I get an answer right or wrong, it doesn't count them.
Please help me.
Below is my code:
#Introduction-ish print statement
print("In this application, we will be playing a coin coss game. For as "\
"many times as you like, we will continue playing the game.")
#def function1():
response=str(input("\nWould you like to run this application? Type 'Y' to run "\
"or 'N' to not run: "))
if response=="N":
print("\nOutcome of Game:")
print("You did not run the application."\
" Nothing happened. You did not play the game.")
#Counters
programCounter=0
hCounter=0
tCounter=0
guessCountR=0
guessCountW=0
#User Input
if response=="Y":
funcGuess=str(input("\nPick one- Type 'H' for Heads or 'T' for Tails: "))
#Coins
import random
#number=random.randint(1,2)
while response !="N" and funcGuess=="H" or funcGuess=="T":
number=random.randint(1,2)
if number==1:
number=="Heads"
hCounter+=1
else:
number=="Tails"
tCounter+=1
if funcGuess==number:
guessCountR+=1
else:
guessCountW+=1
print(number)
response=str(input("Run again?"))
if response=="Y":
funcGuess=str(input("\nPick one- Type 'H' for Heads or 'T' for Tails: "))
if response=="N":
print("\nOutcome of Game:")
print("You guessed ",programCounter, "time(s).")
print("You guessed heads",hCounter, "time(s).")
print("You guessed tails",tCounter, "time(s).")
print("You guessed correctly",guessCountR, "time(s).")
print("You guessed incorrectly",guessCountW, "time(s).")
#Guess Count
guessCount=guessCountR+guessCountW
#paste
#if response =="Y":
#function1()
#else:
#print("\nOutcome of Game:")
#print("You did not run the application."\
#" Nothing happened. You did not play the game.")
I don't mind all the comments. I purposely left them there but if anyone helping finds them useful, please let me know.
Apologies in advanced for the long post.
Problem 1:
On line 34 you're evaluating a variable called funcGuess. It only gets defined on line 26 should you answer 'Y' to the initial question.
Problem 2:
The while loop loops infinitely, because break conditions can never be met. There's no way to assign response the value "N" within the loop. Also, be sure to put both sides of the or evaluation between parentheses in order to evaluate the line correctly
Problem 3:
The correct number and the guess are assigned into variables number and funcGuess, respectively. number is always 1 or 2, and funcGuess is always "H" or "T". Therefore funcGuess == number can never evaluate as True.

Pythonic ways to use 'else' in a for loop [duplicate]

This question already has answers here:
Why does python use 'else' after for and while loops?
(24 answers)
Closed 7 months ago.
I have hardly ever noticed a python program that uses else in a for loop.
I recently used it to perform an action based on the loop variable condition while exiting; as it is in the scope.
What is the pythonic way to use an else in a for loop? Are there any notable use cases?
And, yea. I dislike using break statement. I'd rather set the looping condition complex. Would I be able to get any benefit out of it, if I don't like to use break statement anyway.
Worth noting that for loop has an else since the language inception, the first ever version.
What could be more pythonic than PyPy?
Look at what I discovered starting at line 284 in ctypes_configure/configure.py:
for i in range(0, info['size'] - csize + 1, info['align']):
if layout[i:i+csize] == [None] * csize:
layout_addfield(layout, i, ctype, '_alignment')
break
else:
raise AssertionError("unenforceable alignment %d" % (
info['align'],))
And here, from line 425 in pypy/annotation/annrpython.py (clicky)
if cell.is_constant():
return Constant(cell.const)
else:
for v in known_variables:
if self.bindings[v] is cell:
return v
else:
raise CannotSimplify
In pypy/annotation/binaryop.py, starting at line 751:
def is_((pbc1, pbc2)):
thistype = pairtype(SomePBC, SomePBC)
s = super(thistype, pair(pbc1, pbc2)).is_()
if not s.is_constant():
if not pbc1.can_be_None or not pbc2.can_be_None:
for desc in pbc1.descriptions:
if desc in pbc2.descriptions:
break
else:
s.const = False # no common desc in the two sets
return s
A non-one-liner in pypy/annotation/classdef.py, starting at line 176:
def add_source_for_attribute(self, attr, source):
"""Adds information about a constant source for an attribute.
"""
for cdef in self.getmro():
if attr in cdef.attrs:
# the Attribute() exists already for this class (or a parent)
attrdef = cdef.attrs[attr]
s_prev_value = attrdef.s_value
attrdef.add_constant_source(self, source)
# we should reflow from all the reader's position,
# but as an optimization we try to see if the attribute
# has really been generalized
if attrdef.s_value != s_prev_value:
attrdef.mutated(cdef) # reflow from all read positions
return
else:
# remember the source in self.attr_sources
sources = self.attr_sources.setdefault(attr, [])
sources.append(source)
# register the source in any Attribute found in subclasses,
# to restore invariant (III)
# NB. add_constant_source() may discover new subdefs but the
# right thing will happen to them because self.attr_sources
# was already updated
if not source.instance_level:
for subdef in self.getallsubdefs():
if attr in subdef.attrs:
attrdef = subdef.attrs[attr]
s_prev_value = attrdef.s_value
attrdef.add_constant_source(self, source)
if attrdef.s_value != s_prev_value:
attrdef.mutated(subdef) # reflow from all read positions
Later in the same file, starting at line 307, an example with an illuminating comment:
def generalize_attr(self, attr, s_value=None):
# if the attribute exists in a superclass, generalize there,
# as imposed by invariant (I)
for clsdef in self.getmro():
if attr in clsdef.attrs:
clsdef._generalize_attr(attr, s_value)
break
else:
self._generalize_attr(attr, s_value)
If you have a for loop you don't really have any condition statement. So break is your choice if you like to abort and then else can serve perfectly to handle the case where you were not happy.
for fruit in basket:
if fruit.kind in ['Orange', 'Apple']:
fruit.eat()
break
else:
print 'The basket contains no desirable fruit'
Basically, it simplifies any loop that uses a boolean flag like this:
found = False # <-- initialize boolean
for divisor in range(2, n):
if n % divisor == 0:
found = True # <-- update boolean
break # optional, but continuing would be a waste of time
if found: # <-- check boolean
print n, "is composite"
else:
print n, "is prime"
and allows you to skip the management of the flag:
for divisor in range(2, n):
if n % divisor == 0:
print n, "is composite"
break
else:
print n, "is prime"
Note that there is already a natural place for code to execute when you do find a divisor - right before the break. The only new feature here is a place for code to execute when you tried all divisor and did not find any.
This helps only in conjuction with break. You still need booleans if you can't break (e.g. because you looking for the last match, or have to track several conditions in parallel).
Oh, and BTW, this works for while loops just as well.
any/all
Nowdays, if the only purpose of the loop is a yes-or-no answer, you might be able to write it much shorter with the any()/all() functions with a generator or generator expression that yields booleans:
if any(n % divisor == 0
for divisor in range(2, n)):
print n, "is composite"
else:
print n, "is prime"
Note the elegancy! The code is 1:1 what you want to say!
[This is as effecient as a loop with a break, because the any() function is short-circuiting, only running the generator expression until it yeilds True. In fact it's usually even faster than a loop. Simpler Python code tends to have less overhear.]
This is less workable if you have other side effects - for example if you want to find the divisor. You can still do it (ab)using the fact that non-0 value are true in Python:
divisor = any(d for d in range(2, n) if n % d == 0)
if divisor:
print n, "is divisible by", divisor
else:
print n, "is prime"
but as you see this is getting shaky - wouldn't work if 0 was a possible divisor value...
Without using break, else blocks have no benefit for for and while statements. The following two examples are equivalent:
for x in range(10):
pass
else:
print "else"
for x in range(10):
pass
print "else"
The only reason for using else with for or while is to do something after the loop if it terminated normally, meaning without an explicit break.
After a lot of thinking, I can finally come up with a case where this might be useful:
def commit_changes(directory):
for file in directory:
if file_is_modified(file):
break
else:
# No changes
return False
# Something has been changed
send_directory_to_server()
return True
Perhaps the best answer comes from the official Python tutorial:
break and continue Statements, and else Clauses on Loops:
Loop statements may have an else
clause; it is executed when the loop
terminates through exhaustion of the
list (with for) or when the condition
becomes false (with while), but not
when the loop is terminated by a break
statement
I was introduced to a wonderful idiom in which you can use a for/break/else scheme with an iterator to save both time and LOC. The example at hand was searching for the candidate for an incompletely qualified path. If you care to see the original context, please see the original question.
def match(path, actual):
path = path.strip('/').split('/')
actual = iter(actual.strip('/').split('/'))
for pathitem in path:
for item in actual:
if pathitem == item:
break
else:
return False
return True
What makes the use of for/else so great here is the elegance of avoiding juggling a confusing boolean around. Without else, but hoping to achieve the same amount of short-circuiting, it might be written like so:
def match(path, actual):
path = path.strip('/').split('/')
actual = iter(actual.strip('/').split('/'))
failed = True
for pathitem in path:
failed = True
for item in actual:
if pathitem == item:
failed = False
break
if failed:
break
return not failed
I think the use of else makes it more elegant and more obvious.
A use case of the else clause of loops is breaking out of nested loops:
while True:
for item in iterable:
if condition:
break
suite
else:
continue
break
It avoids repeating conditions:
while not condition:
for item in iterable:
if condition:
break
suite
Here you go:
a = ('y','a','y')
for x in a:
print x,
else:
print '!'
It's for the caboose.
edit:
# What happens if we add the ! to a list?
def side_effect(your_list):
your_list.extend('!')
for x in your_list:
print x,
claimant = ['A',' ','g','u','r','u']
side_effect(claimant)
print claimant[-1]
# oh no, claimant now ends with a '!'
edit:
a = (("this","is"),("a","contrived","example"),("of","the","caboose","idiom"))
for b in a:
for c in b:
print c,
if "is" == c:
break
else:
print

Resources