python: simulation termination - python

I just had a quick question, for the following simulation, if one event happens , lets say birth would it automatically increase the time_elapsed, or will it go to death and check the death would happen and do that?
while time_elapsed < end_time :
event=birth () +death () +infection()
choice=random.random()*event
choice -= birth()
time_elapsed += random.expovariate(event)
if choice < 0 :
do_birth()
continue
choice -= death()
if choice < 0:
do_death()
continue
choice -= total_infection_rate()
if choice < 0:
do_infection()
continue

In your code above, it will check all the conditional statments until any one evaluates to True. If it does, it will execute the code in that block and then the continue will jump back to the start of the loop, skipping all the other if statements (regardless of whether they would have been True or not). If you want to perform only one of the cases, you would do it as:
if number >= 0:
print('Number is positive')
else:
print('Number is negative')
Here, python will evaluate the if number >= 0 block and if it is True, it will print the 'Number is positive' and then skip the else statement. If if number >= 0 block had evaluated to False, python would simply execute the code in the else block and then move on.
For more detailed cases, you can also use elif. Here is a similar example:
if number > 0:
print('Number is positive')
elif number < 0:
print('Number is negative')
else:
print('Number is 0')
It follows the same logic. Python will start at the top of the block and keep evaluating each condition in the if/elif blocks until any condition evaluates to True, at which point it will execute the code under that block and then skip all the other conditional statements in that group.

Related

Program won't loop or add to a list

I have made (or more, I'm trying to make) a program to help me calculate some figures.
I have some levels that each give a reward and to give out the rewards I prefer to not insert each amount and add them all up to get the totals.
I've made it so that I write the level number, it adds the amount to a list, it loops again, I insert a different number etc.
But it doesn't loop or add the numbers to the list.
Heres my super un-compact code:
lists = []
total = 0
def moneyz():
level=input('-> ')
print('g') #just a testing bookmark
print(level) #same here
if level==1:
print('oo') #and here
lists.apped('150')
total==total+150
elif level == 2:
lists.apped('225')
total==total+225
moneyz()
elif level == 3:
lists.apped('330')
total==total+330
moneyz()
elif level == 4:
lists.apped('500')
total==total+500
moneyz()
elif level == 5:
lists.apped('1000')
total==total+1000
moneyz()
elif level == 6:
lists.apped('1500')
total==total+1500
moneyz()
elif level == 7:
lists.apped('2250')
total==total+2250
moneyz()
elif level == 8:
lists.apped('3400')
total==total+3400
moneyz()
elif level == 9:
lists.apped('5000')
total==total+5000
moneyz()
elif level == 10:
lists.apped('15000')
total==total+15000
moneyz()
moneyz()
print(lists)
print(total)
I can see three bugs in this code:
level is a str, so it will never equal an int. None of your if checks will ever be satisfied, which is why your function isn't recursing. A way to spot this in debugging would have been to add a print(repr(level)) after you receive the input; you'd see that it's a value like '1' (a string) instead of 1 (an integer).
There is no such thing as apped(), so once you hit that line of code (which currently isn't happening because your if checks never match), it'd raise an AttributeError.
Your total is never going to increase because you're using the == (equality check) operator rather than the = (assignment) operator.
Here's a much shorter (working) version of the program, using a simple lookup table in place of a bunch of if statements:
# Rewards for levels 0 to 10.
rewards = [0, 150, 225, 330, 500, 1000, 1500, 2250, 3400, 5000, 15000]
# Running totals.
lists = []
total = 0
while True:
# Get reward level from the user. If not a valid reward level, stop.
level = input('-> ')
try:
level_num = int(level)
except ValueError:
break
if level_num not in range(len(rewards)):
break
# Add the reward to the lists and the total.
reward = rewards[level_num]
lists.append(reward)
total += reward
# Final output.
print(lists)
print(total)
You are using level==1where level is a string as input() returns a string and you are comparing it with int.
You should try level=='1' or convert level to int by level = int(input("->")).
Also, list has append() method and not apped()
Also, total==total+1000 won't help for adding. It will just check if value of total is equal to total plus 1000. You should use total = total + 1000 for adding value.
Here is one sample modified if block:
if level=='1':
print('oo') #and here
lists.append('150')
total=total+150
Hope it helps.

While loop that's meant to be infinite freezes after first cycle

My goal is to make a program that prints onscreen all of the prime numbers it can find, however I have this issue where the while loop runs only once, instead of repeating forever.
def isPrime(num):
if num < 2:
return False
if num == 2:
return True
if num % 2 == 0:
return False
i = 3
while i * i <= num:
if num % i == 0:
return False
i += 2
x = 1
while True:
x += 1
if isPrime(x):
print (x)
I also have tried adding print("You can see this.") at the very end of the code, and it runs, but only once.
I'm sure it's a common mistake, since Python is very strict on indentation, but could you guys help me discover it? Thanks in advance.
You need to return True at the very end, after and outside the final loop. Otherwise the function ends without explicitly returning anything, so it implicitly returns None which is interpreted as false.
The i +=2 is indented too deep, the inner loop never quits.
It should read
while i * i <= num:
if num % i == 0:
return False
i += 2
Otherwise i never increases and the loop goes on and on and on.

Square factorization in python 3?

Note - Go down to the edits if you want the more recent code, look here if you want to see the original question. I have made edits to the code, however, so mistakes in this code block may be outdated.
As a self-taught Python 3 programmer, I have been working on a way to simplify radical expressions. The one part of the program that does not work, however, is the square factorization. I have a function that detects square numbers, which works fine. The function that does not work is the following-
def sqfactorslist(num):
factors = []
counter = num // 2 + 1
while counter > 0:
if counter == 1:
factors.append(num) #if no square ints other than 1 square into num, append and finish.
while is_square(counter) == True and counter != 1: #If counter is a valid square integer, append it's square and subtract it from num.
if (counter ** 2) >= num:
factors.append(counter ** 2)
num -= counter ** 2
else: #Else, continue with a program.
break
if counter > 0:
counter -= 1 #If counter more than 0, subtract 1 from it
else:
break #If number is equal to or less than 0, break
return factors #If the input is 32, this should return 16 and 2.
It doesn't return anything other than an infinite loop. Anyone know whats wrong?
Edit 1 -- I have changed the program so that it runs, but now I have a stranger issue: If I input a square number as num, for example 16, I get a number larger than the input, e.x. 81, in the return list. I get no returned elements for a non-square number.
To make it run, I indented the first if statement after the end of the second while loop.
Edit 2 -- I have changed the program again, but I come up with another issue similar to the one above. After eliminating another mistake, where I squared numbers already shown to be square, found in the second while loop, the program now has a new problem - If I use a non-square integer, it returns an empty list, and if I use a square integer, like 16, it gives me an infinite loop. Current code shown below --
def findsqfactors(num):
factors = []
counter = num // 2 + 1
while counter > 0:
if counter == 1:
factors.append(num) #If no square ints other than 1 square into num, append then finish.
while is_square(counter) == True and counter != 1: #
if counter >= num:
factors.append(counter)
num -= counter
else:
break
if counter > 0:
counter -= 1
else:
break
return factors

Python indentation, allignment of IFs and ELSEs

I am new to python and i am still strugling to understand how the sytnax works, how you need to allign your If and else to make it work correctly. How do i really know which else goes with which if? especially when using nested code blocks.
In the code below for the else followed by the comment Prime! from what i understand that else goes with the statement if (n % div == 0): but then why is it alligned with the FOR statement instead?
the last else statement i think goes with if n == 2: but the else is not alligned with it, instead it is after. For the same statement if n == 2: why is n += 1 alligned before pime_count +=1 and not after it.
I understand that the placement of the Else and if is very important because if i decided to move any of them the code stops working. What i can't seem to understand is how does python know which else goes with which if, if the allignment doesnt seem to be consistent.
#!/usr/bin/env python
#
# Problem Set 1a
#
# A program that computes and prints the 1000th prime number.
# Finds primes using trial division (least efficient method)
#------------------------------------------------------------
prime_count = 0
n = 2
while (prime_count <= 1000):
#if even, check for 2, the only even prime
if (n % 2 == 0):
if n == 2:
prime_count += 1
n += 1
else:
# number is odd, possible prime
for div in range(3, n, 2):
if (n % div == 0):
# not a prime
n += 1
break
else:
# prime!
prime_count += 1
if prime_count == 1000:
print "The 1000 prime is", n
else:
n += 1
The rule is very simple: the else clause must have the same indentation as the statement it refers to (most commonly, an if statement).
Now, here:
for div in range(3, n, 2):
if (n % div == 0):
# not a prime
n += 1
break
else:
...
you are not using if-else, you are using for-else!
This construct means "execute the else block unless the loop has terminated through a break".
See for ... else in Python for a discussion.
An if goes with an else at the same indentation, so long as there are no other things at lower indentation between them. They have to be in the same "block". However, in your case, the else that's followed by # prime! is not actually joined to an if at all, but rather to the for div in range(3, n, 2): loop before it!
An else attached to a for loop means "execute this code if the for loop completed without hitting a break statement". It can be useful sometimes, but it is often confusing for people who haven't encountered it before!
I think this can help you to understand how python indentation works http://psung.blogspot.com/2007/12/for-else-in-python.html
In a construct like this one:
for i in foo:
if bar(i):
break
else:
baz()
the else suite is executed after the for, but only if the for terminates normally (not by a break).
In other situations else goes after if
There are 2 rules which are fairly simple,
The indent of the if and else have to be the same
for x in range(15):
if x > 10:
print 'x is more than 10'
else:
print 'x is less than or equal to 10'
Nothing with an indent lower than or equal to that of if and elseshould come in between them
So, this is invalid/ will raise a SyntaxError.
for x in range(15):
if x > 10:
print 'x is more than 10'
print x
else:
print 'x is less than or equal to 10'
Also, As stated in PEP 8
Use 4 spaces per indentation level.
for div in range(3, n, 2):
if (n % div == 0):
# not a prime
n += 1
break
else: # at same indent as for
# prime!
Also, your indent above means for...else loop is made (here else clause is executed if the for loop is exited using break), not if..else.

Difference between multiple if's and elif's?

In python, is there a difference between say:
if text == 'sometext':
print(text)
if text == 'nottext':
print("notanytext")
and
if text == 'sometext':
print(text)
elif text == 'nottext':
print("notanytext")
Just wondering if multiple ifs could cause any unwanted problems and if it would be better practice to use elifs.
Multiple if's means your code would go and check all the if conditions, where as in case of elif, if one if condition satisfies it would not check other conditions..
An other easy way to see the difference between the use of if and elif is this example here:
def analyzeAge( age ):
if age < 21:
print "You are a child"
if age >= 21: #Greater than or equal to
print "You are an adult"
else: #Handle all cases where 'age' is negative
print "The age must be a positive integer!"
analyzeAge( 18 ) #Calling the function
>You are a child
>The age must be a positive integer!
Here you can see that when 18 is used as input the answer is (surprisingly) 2 sentences. That is wrong. It should only be the first sentence.
That is because BOTH if statements are being evaluated. The computer sees them as two separate statements:
The first one is true for 18 and so "You are a child" is printed.
The second if statement is false and therefore the else part is
executed printing "The age must be a positive integer".
The elif fixes this and makes the two if statements 'stick together' as one:
def analyzeAge( age ):
if age < 21 and age > 0:
print "You are a child"
elif age >= 21:
print "You are an adult"
else: #Handle all cases where 'age' is negative
print "The age must be a positive integer!"
analyzeAge( 18 ) #Calling the function
>You are a child
Edit: corrected spelling
def multipleif(text):
if text == 'sometext':
print(text)
if text == 'nottext':
print("notanytext")
def eliftest(text):
if text == 'sometext':
print(text)
elif text == 'nottext':
print("notanytext")
text = "sometext"
timeit multipleif(text)
100000 loops, best of 3: 5.22 us per loop
timeit eliftest(text)
100000 loops, best of 3: 5.13 us per loop
You can see that elif is slightly faster. This would be more apparent if there were more ifs and more elifs.
Here's another way of thinking about this:
Let's say you have two specific conditions that an if/else catchall structure will not suffice:
Example:
I have a 3 X 3 tic-tac-toe board and I want to print the coordinates of both diagonals and not the rest of the squares.
I decide to use and if/elif structure instead...
for row in range(3):
for col in range(3):
if row == col:
print('diagonal1', '(%s, %s)' % (i, j))
elif col == 2 - row:
print('\t' * 6 + 'diagonal2', '(%s, %s)' % (i, j))
The output is:
diagonal1 (0, 0)
diagonal2 (0, 2)
diagonal1 (1, 1)
diagonal2 (2, 0)
diagonal1 (2, 2)
But wait! I wanted to include all three coordinates of diagonal2 since (1, 1) is part of diagonal 2 as well.
The 'elif' caused a dependency with the 'if' so that if the original 'if' was satisfied the 'elif' will not initiate even if the 'elif' logic satisfied the condition as well.
Let's change the second 'elif' to an 'if' instead.
for row in range(3):
for col in range(3):
if row == col:
print('diagonal1', '(%s, %s)' % (i, j))
if col == 2 - row:
print('\t' * 6 + 'diagonal2', '(%s, %s)' % (i, j))
I now get the output that I wanted because the two 'if' statements are mutually exclusive.
diagonal1 (0, 0)
diagonal2 (0, 2)
diagonal1 (1, 1)
diagonal2 (1, 1)
diagonal2 (2, 0)
diagonal1 (2, 2)
Ultimately knowing what kind or result you want to achieve will determine what type of conditional relationship/structure you code.
elifis just a fancy way of expressing else: if,
Multiple ifs execute multiple branches after testing, while the elifs are mutually exclusivly, execute acutally one branch after testing.
Take user2333594's examples
def analyzeAge( age ):
if age < 21:
print "You are a child"
elif age > 21:
print "You are an adult"
else: #Handle all cases were 'age' is negative
print "The age must be a positive integer!"
could be rephrased as:
def analyzeAge( age ):
if age < 21:
print "You are a child"
else:
if age > 21:
print "You are an adult"
else: #Handle all cases were 'age' is negative
print "The age must be a positive integer!"
The other example could be :
def analyzeAge( age ):
if age < 21:
print "You are a child"
else: pass #the if end
if age > 21:
print "You are an adult"
else: #Handle all cases were 'age' is negative
print "The age must be a positive integer!"
In your above example there are differences, because your second code has indented the elif, it would be actually inside the if block, and is a syntactically and logically incorrect in this example.
Python uses line indentions to define code blocks (most C like languages use {} to enclose a block of code, but python uses line indentions), so when you are coding, you should consider the indentions seriously.
your sample 1:
if text == 'sometext':
print(text)
elif text == 'nottext':
print("notanytext")
both if and elif are indented the same, so they are related to the same logic.
your second example:
if text == 'sometext':
print(text)
elif text == 'nottext':
print("notanytext")
elif is indented more than if, before another block encloses it, so it is considered inside the if block. and since inside the if there is no other nested if, the elif is being considered as a syntax error by Python interpreter.
When you use multiple if, your code will go back in every if statement to check the whether the expression suits your condition.
Sometimes, there are instances of sending many results for a single expression which you will not even expect.
But using elif terminates the process when the expression suits any of your condition.
Here's how I break down control flow statements:
# if: unaffected by preceding control statements
def if_example():
if True:
print('hey')
if True:
print('hi') # will execute *even* if previous statements execute
will print hey and hi
# elif: affected by preceding control statements
def elif_example():
if False:
print('hey')
elif True:
print('hi') # will execute *only* if previous statement *do not*
will print hi only because the preceding statement evaluated to False
# else: affected by preceding control statements
def else_example():
if False:
print('hey')
elif False:
print('hi')
else:
print('hello') # will execute *only* if *all* previous statements *do not*
will print hello because all preceding statements failed to execute
In the case of:
if text == 'sometext':
print(text)
if text == 'nottext':
print("notanytext")
All the if statements at the same indentation level are executed even if only the first if statement is True.
In the case of:
if text == 'sometext':
print(text)
elif text == 'nottext':
print("notanytext")
When an if statement is True, the preceding statements are omitted/ not-executed.

Categories

Resources