Restart current iteration in Python - python

I want to restart the current iteration of the first for loop when testing12(bad_order, order) == True. I have tried to use continue but it skips over the iteration which is not what I want.
bad_order = []
order = []
for iteration in range(0, 10):
args = []
print("\n def test%d(self):" % (iteration))
for input in range(num_arguments):
args.append(pick_type())
order = args
if testing12(bad_order, order) == True:
continue
try:
result = target(*args)
code = test_to_string(target, args, result)
except Exception as error:
bad_order = args
code = test_to_string_exc(target, args, error)

You can add an inner while loop which will in effect repeat the outer loop iteration until it exits. If you can put the repeat condition in the while test, then you're done:
for iteration in range(0, 10):
while some_condition:
...
If not, you can use a while True loop, put an unconditional break at the bottom, and use a continue to repeat:
for iteration in range(0, 10):
while True:
...
if continue_condition:
continue
...
break

you can also change the:
for iteration in range(0,10):
to
iteration =0
while iteration < 10 :
and increment iteration only when no repeat is needed

You just need to add an infinite while loop that breaks at the end of the iteration.
Then you can restart the iteration as often as needed.
bad_order = []
order = []
for iteration in range(0, 10):
while True: #
args = []
print("\n def test%d(self):" % (iteration))
for input in range(num_arguments):
args.append(pick_type())
order = args
if testing12(bad_order, order) == True:
continue
try:
result = target(*args)
code = test_to_string(target, args, result)
except Exception as error:
bad_order = args
code = test_to_string_exc(target, args, error)
break #

Related

Go back to specific number in a for-loop

I have the following code:
def five_numbers():
my_list = []
for i in range(1, 6):
user_nr = check_if_number_is_1_to_25(input("Number " + str(i) + ": "))
my_list.append(user_nr)
return my_list
def check_if_number_is_1_to_25(number):
if number.isalpha():
print("Enter a number between 1 and 25.")
# Here I want to go back to five_numbers() and the number x (for example number 4)
Now I want to check if the input contains any letters. If it has, I want to print a message and then I want to go back to the number that the user was on earlier. I've tried to return five_numbers() but then the user will start from the beginning.
I appreciate all the help.
Add a keyword arg for num and default it to None:
def five_numbers(num=None):
my_list = []
if num is None:
for i in range(1, 6):
user_nr = check_if_number_is_1_to_25(input("Number " + str(i) + ": "))
my_list.append(user_nr)
else:
# do other stuff with num (4) here...
return my_list
def check_if_number_is_1_to_25(number):
if number.isalpha():
print("Enter a number between 1 and 25.")
five_numbers(4)
You can use a while loop to keep asking the user for a valid input until the user enters one. You should also make the check function raise an exception instead so the caller can catch the exception and retry the input:
def five_numbers():
my_list = []
for i in range(1, 6):
while True:
user_nr = input("Number " + str(i) + ": ")
try:
check_if_number_is_1_to_25(user_nr)
break
except ValueError as e:
print(str(e))
my_list.append(user_nr)
return my_list
def check_if_number_is_1_to_25(number):
if number.isalpha():
raise ValueError('Enter a number between 1 and 25.')
Don't use a for loop, use a while loop with the list length as its condition. Make the check function return a boolean and use it to decide whether to append to the list.
def five_numbers():
my_list = []
while len(my_list) < 5:
user_nr = input("Number {}: ".format(len(my_list)+1))
if check_if_number_is_1_to_25(user_nr):
my_list.append(user_nr)
else:
print("Enter a number between 1 and 25.")
return my_list
def check_if_number_is_1_to_25(number):
return number.isdigit() and (1 <= float(number) <= 25)

Python: Failing to break out of while loop with "SyntaxError: 'break' outside loop"

I am developing a breadth-first-search algorithm for a factorization problem and am running into an interesting/confusing bug when attempting to break out of a while loop. If you run the code below, it will fail inside the "construct_path" method, stating :
File "main.py", line 96
break
SyntaxError: 'break' outside loop
but I am inside of a while loop! If anyone could give me some advice on this issue, I would really appreciate it. Thanks in advance.
from numpy import random
import itertools
import Queue
#Finding multiples, BFS problem
#Given input of list with unique integers 0 - 9 and n = range(0,1000000), calculate smallest multiple of n and unique combination of values in the list
#Example : Input : list = {0,1,2} , n = 3,
# output = 12
# Input : list = {0,1,2} , n = 50
# Output = 200
class Problem:
def __init__(self):
self.n = random.randint(0,10000000)
listSize = random.randint(1,9)
mainSet = set()
self.mainList = []
while True:
toAdd = random.randint(0,9)
if(toAdd not in self.mainList):
self.mainList.append(toAdd)
if(len(self.mainList) == listSize):
break
def get_start_state(self):
s = ''.join(map(str, self.mainList))
return int(s)
def is_goal(self, state):
return True
def get_sucessors(self):
print "Getting successors"
def breadth_first_search(problem):
# a FIFO open_set
open_set = Queue.Queue()
# an empty set to maintain visited nodes
closed_set = set()
# a dictionary to maintain meta information (used for path formation)
meta = dict() # key -> (parent state, action to reach child)
# initialize
start = problem.get_start_state()
meta[start] = (None, None)
open_set.put(start)
while not open_set.empty():
parent_state = open_set.get()
print "{} {}".format("parent_state is ", parent_state)
if problem.is_goal(parent_state):
return construct_path(parent_state, meta)
for (child_state, action) in problem.get_successors(parent_state):
if child_state in closed_set:
continue
if child_state not in open_set:
meta[child_state] = (parent_state, action)
open_set.put(child_state)
closed_set.add(parent_state)
#collect path to desired answer
def construct_path(state, meta):
action_list = list()
while True:
row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
return action_list.reverse()
x = Problem()
breadth_first_search(x)
Could be that you have a mix of tabs and spaces so that the break in line 96 looks like it is indented to be below action_list.append(action) but effectively it is below the while. That would explain the error at least.
It is just a guess. But it could be like this, using a visible tabwidth of 4 in the editor:
→ while True:
→ → row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
To the Python interpreter this looks like this (because it assumes a tabwidth of 8):
→ while True:
→ → row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
This is still valid but obviously means a different thing and would put your break outside of the while loop.

Repeatedly replacing parts of a string in a loop

I created a HTML text cleaner, which deletes data between tags.
It's working fine on one iteration, but not in a loop.
The problem is, I cannot save newhtml as a variable due to Python's string immutability.
So, my loop is only working for the last iteration of the function return.
What would be the best practice in such a situation?
def find_all(a_str, sub):
start = 0
while True:
start = a_str.find(sub, start)
if start == -1: return
yield start
start += len(sub) # use start += 1 to find overlapping matches
def replace_string(index1, index2, mainstring):
replacementstring = ''
return mainstring.replace(mainstring[index1:index2], replacementstring)
def strip_images(html):
begin_indexes = list(find_all(html, '<DESCRIPTION>GRAPHIC'))
end_indexes = list(find_all(html, '</TEXT>'))
for i in range(len(begin_indexes)):
if begin_indexes[i] > end_indexes[i]:
end_indexes.pop(0)
else:
if len(begin_indexes) == len(end_indexes):
break
for i in range(len(begin_indexes)):
#code problem is here--
newhtml = replace_string(begin_indexes[i],end_indexes[i], html)
if i == len(begin_indexes) - 1:
return newhtml
#code only returns one iteration
var = strip_images(html)
print var
Your current issue is that html never changes within the loop. So, your input will always be for the first iteration, regardless of the length of the lists.
The solution here follows these steps
Assign the string to the original value before the loop
Edit within the loop, passing in the current content, returning a replaced string
Return from the function after the loop
newhtml = html
for begin, end in zip(begin_indexes, end_indexes):
newhtml = replace_string(begin, end, newhtml)
return newhtml
Got it working, here's the code snippet. It's not pretty but it's doing the job of removing text between those two tags:
def find_all(a_str, sub):
start = 0
while True:
start = a_str.find(sub, start)
if start == -1: return
yield start
start += len(sub) # use start += 1 to find overlapping matches
def strip_images(html):
begin_indexes = list(find_all(html, '<DESCRIPTION>GRAPHIC'))
end_indexes = list(find_all(html, '</TEXT>'))
for i in range(len(begin_indexes)):
if begin_indexes[i] > end_indexes[i]:
end_indexes.pop(0)
else:
if len(begin_indexes) == len(end_indexes):
break
newhtml = html
begin_indexes2 = begin_indexes[::-1]
end_indexes2 = end_indexes[::-1]
for i in range(len(begin_indexes2)):
#for i, value in enumerate(begin_indexes,0):
#end_indexes.reset_index(drop=True)
newhtml = list(newhtml)
del newhtml[begin_indexes2[i]:end_indexes2[i]]
if i == len(begin_indexes2) - 1:
str1 = ''.join(newhtml)
return str1

Python: Do not map empty result of multiprocessing.Pool( )

Program have function that may return None value, for minimize spend time this function calling in parallel workers.
In code below, result of this function have the "None" values, how to exclude this is values from the "ret"?
#!/usr/bin/python
import sys,multiprocessing,time
maxNumber = sys.maxint+2
def numGen():
cnt=0
while cnt < maxNumber:
cnt +=1
yield cnt
def oddCheck(num):
global maxNumber
# time.sleep(1)
if not bool(num%1000000):
print "[%s%%] %s" % (int((num/maxNumber)*100),num)
if num%2:
return num
pool = multiprocessing.Pool( )
if sys.maxint < maxNumber:
print "We have problem on %s"%sys.maxint
# quit()
ret = pool.imap(oddCheck, numGen())
pool.close()
pool.join()
for x in ret:
print x
oddCheck returns None when num is not a even number (you do not have a return statement in this case, so None will be returned).
If you want to avoid None results, just use a list comprehension to filter them:
ret = [x for x in pool.imap(oddCheck, numGen()) if x is not None]
It should do the trick ;-)

How to ask user for a series of number and return the sum of all numbers excluding the max number?

So I need to create a function in python that asks the user to input numbers and enter end when done. After that I need to compute the sum of the numbers enter excluding the max number. (i.e if the user entered 20, 50, and 100 the sum would be 70)
So for I have this which loops input until user inputs the word end:
def excludeMax():
while True:
result = input('Enter next number or end:')
if (result == 'end'):
break
This looks like what you are looking for.
def excludeMax():
numbers = []
while True:
result = input('Enter next number or end:')
if (result == 'end'):
break
else:
numbers.append(result)
# notice this is after the loop
numbers.remove(max(numbers))
return sum(numbers)
Simply sort it and then add up a slice:
def exclude_max():
return sum(sorted(map(int, iter(lambda: input('Enter next number or end: '), 'end')))[:-1])
Result:
>>> exclude_max()
Enter next number or end: 20
Enter next number or end: 50
Enter next number or end: 100
Enter next number or end: end
70
Place all numerical input into a list. If you see an end, break from the while loop. Once you've exited the while loop, remove the max element from the list (e.g., lst.remove(max(list))). Finally, get the sum via sum(lst).
Approach 1: No temp lists and sort needed in this approach. Excludes just one of the max numbers(doesn't deal with duplicates)
def excludeMax():
biggest_sof_far = None
sum_of_inputs = 0
while True:
result = input('Enter next number or end:')
if result == 'end':
break
if biggest_sof_far == None:
biggest_sof_far = result
elif result > biggest_sof_far:
sum_of_inputs += biggest_sof_far
biggest_sof_far = result
else:
sum_of_inputs += result
return sum_of_inputs
if __name__ == "__main__":
print excludeMax()
Approach 2: Using a temp list (increases space complexity) and sort and sum on list(increases time complexity). This to excludes just one max numbers(doesn't deal with duplicates)
def excludeMax():
input_numbers = []
while True:
result = input('Enter next number or end:')
if result == 'end':
break
input_numbers.append(result)
input_numbers.sort()
return sum(input_numbers[:-1])
if __name__ == "__main__":
print excludeMax()
Both the approaches assume that you want to exclude just one max element. If you want to exclude all max elements(in case of duplicate max numbers):
Approach 1: Excludes even the duplicate max numbers
def excludeMax():
biggest_sof_far = None
sum_of_inputs = 0
while True:
result = input('Enter next number or end:')
if result == 'end':
break
if biggest_sof_far == None:
biggest_sof_far = result
elif result == biggest_sof_far:
pass
elif result > biggest_sof_far:
sum_of_inputs += biggest_sof_far
biggest_sof_far = result
else:
sum_of_inputs += result
return sum_of_inputs
if __name__ == "__main__":
print excludeMax()
Approach 2: Excludes even the duplicate max numbers
def excludeMax():
input_numbers = []
while True:
result = input('Enter next number or end:')
if result == 'end':
break
input_numbers.append(result)
input_numbers.sort()
omit_till_index = -1
input_len = len(input_numbers)
while input_len > -omit_till_index and \
input_numbers[omit_till_index] == input_numbers[omit_till_index-1]:
omit_till_index = omit_till_index-1
return sum(input_numbers[:omit_till_index])
if __name__ == "__main__":
print excludeMax()
In your loop append all input values to a list (if not 'end'). After that sort list in place and compute sum for list[:-1] (gives you the list without the last element).
In code:
numbers = []
def excludeMax():
while True:
result = input('Enter next number or end:')
if (result == 'end'):
break
else:
numbers.append(result)
numbers.sort()
sum_numbers = sum(numbers[:-1])

Categories

Resources