0

I've been attempting at my first program in Python and have largely been able to find existing answers to my questions, but now I'm really stuck.

The code is as follows:

from shapely import geometry, ops

main_condition = True
line = geometry.LineString(((0,0),(5,5)))

while main_condition:
   # do some geometry stuff with line

   if second_condition:
      return line
      main_condition = False

   else:
      line_parallel = line.parallel_offset(«arg1»,«arg2»)
      line = line_parallel
      #loop again

So I have a line, that I want to offset until a condition is met. My problem is that the parameters I want to vary are an argument of the shapely line_parallel function. Now the arguments I want to vary are as follows:

«arg1»: This parameter is a float and is the offset for the new parallel line. I'd like this to be 0.001, 0.001, 0.002, 0.002, 0.003, 0.003, and so on, repeating once and then moving to the next number.

«arg2»: This parameter is a string and is if the offset if to the 'left' or 'right'. I want this to vary between 'left' and 'right' each time the main loop is run.

Hopefully that's not too confusing, but essentially the idea is that the line offsets first 0.001 'left', then 0.001 'right', then 0.002 'left', then 0.002 'right' and so on each time offsetting to a further and further away position to either side of the original line until the condition is met.

Any idea on what might be the best way of having a varying argument to a function inside the while loop?

Georgy
  • 12,464
  • 7
  • 65
  • 73
Miguel
  • 401
  • 5
  • 13
  • Does this answer your question? [Get the cartesian product of a series of lists?](https://stackoverflow.com/questions/533905/get-the-cartesian-product-of-a-series-of-lists) – Georgy Jun 17 '20 at 09:26
  • Basically you will need two iterables: one for `0.001, 0.002,...` and the other one for `left` and `right`. And then simply iterate over their Cartesian product. If the number of the first parameter is fixed, you could write: `for distance, side in product(np.linspace(0.001, 0.003, 3), ('left', 'right')): ...`, or if you want to change the distances indefinitely, change the first iterable to `(0.001*x for x in itertools.count(1))`. – Georgy Jun 17 '20 at 09:33
  • Logically it does make sense. However, I tried the following test to understand the process: `for distance, side in itertools.product((0.001*x for x in itertools.count(1)), ('left', 'right')): print("I'm inside the for loop") print(distance) print(side) time.sleep(1)` But nothing prints out, i.e. I'm not being able to get inside the for loop as far as I understand. Any idea what I'm doing wrong? – Miguel Jun 17 '20 at 10:25
  • Sorry, I should've tested that before suggesting. I was sure that it would work, but, as I just found out, [`itertools.product`](https://stackoverflow.com/q/45586863/7851470) converts the arguments to tuples, so it will eat your memory by trying to convert the infinite iterator. I'll retract my flag. Here is a question similar to yours, though: [How to get Cartesian product of two iterables when one of them is infinite](https://stackoverflow.com/q/60166248/7851470). It should answer your question. – Georgy Jun 17 '20 at 12:08

1 Answers1

0

Simple solution

import itertools

def my_loop():
  for i in itertools.count():
    for dir in ['right', 'left']:
      arg1 = i * 0.001
      arg2 = dir
      # rest
      if condition:
        return
my_loop()

However, using generators would be a better solution in my opinion. But, since you're still a beginner, I'll refrain from posting that solution.

Cnoor0171
  • 368
  • 3
  • 12