4

I want to achieve an algorithm, which allows to return some results according to inputs.

I pass those values ( Changeable, values varies)

b, c, a, li = 200, 30, 3 , [3,3]

into a function with algorithm, and my result should return as a list.

[x1, x2, x3, ...]

x1, xn is just for illustration.

Sample of code:

b, c, a, li = 200, 30, 3 , [1,1]

def func(b,c,a,li):
    for index, item in enumerate(li):
        if index == 0:
            if a %2 == 0:
                Result = []
                start= 0
                for num in range(a):
                    Result[:0]=[start+num*c]
                    Result[-1:]=[b-num*c]
            else:
                Result = []
                start= 0
                for num in range(a):
                    Result[:0]=[start+num*c]
                    Result[-1:]=[b-num*c]
    return Result


g = func(b,c,a,li)
print(g)

Output:

[60, 30, 140]

I expect to get an output as: [0, 100 ,200]

What I want to achieve is as below:

For instance in above example:

A for-loop inside function first checks first value of list which is 1. then place x1 and second value of list which is 1 and place x2, the remaining is 1 , this should be placed as x3, se figur, and xn values are calulated as x1=b-b=0, x2=b, x3= x1 + b/(a-len(li)+1)

enter image description here

Another example with even numbers:

b, c, a, li = 300, 35, 4 , [2,2]

enter image description here

Output:

[ 0, 35, 265, 300]

Another example with odd numbers:

b, c, a, li = 400, 25, 5 , [2,2]

enter image description here

Output:

[ 0, 25, 200, 375, 400] 

Another example with some other numbers:

b, c, a, li = 350, 40, 3 , [4,2]

Output:

[ 0, 40, 350] 

I really find it difficult to write an algorithm pattern which solves the puzzle. I appreciate much any help. Thanks.

Pavel.D
  • 561
  • 1
  • 15
  • 41
  • Please fix your function indentation. Is the `return` statement really inside the `for` loop, or is it after the loop? – Barmar Jun 22 '19 at 00:03
  • 1
    You should use `else:` instead of `if a %2 != 0` since the second condition is simply the opposite of the first one. – Barmar Jun 22 '19 at 00:03
  • 1
    You are making a new `Result` for each item of `li`. The function's return value only contains the result of the last iteration of of the for loop. – wwii Jun 22 '19 at 00:27
  • 1
    The `if` and `else` suites are exactly the same – wwii Jun 22 '19 at 00:34
  • 3
    Can your explain in words the algorithm/transformation/rules/logic/calculations. The graphics just aren't doing anything for me. – wwii Jun 22 '19 at 00:42
  • Yes but i want final result to be one list. What comes after if and else statement should be an algorithm which explains above theory, but it is here i need help? – Pavel.D Jun 22 '19 at 00:42
  • For your example with inputs -`b, c, a, li = 200, 30, 3 , [1,1]` and desired outputs `[0, 150 ,200]` - the value for `x3` does not match your stated calc of `x3= x1 + b/(a-len(li)+1)`. – wwii Jun 22 '19 at 00:48
  • Okay i would explain it with word. Sorry my mistake, it is corrected to [0,100,200] – Pavel.D Jun 22 '19 at 00:50
  • Consider b is a length ex. 200 and a is number of points or coordinates on b length, but points could locate according to li list and li list is always [ value 1, value2]. Take value 1 from li list if is 1 then just one x1 places in the begining, if value 1 is 2 then x1 places at start of b and x3 places after x1 with x1+a, check value 2 from li list and place x2 at end of length b. – Pavel.D Jun 22 '19 at 01:02
  • If a = 5 and li= [2,2], take value 1 and start from 1 and place x1 at start of b, then by value 1 with 2 place x3 after x1 with a distance. The same logic to value 2 from li list – Pavel.D Jun 22 '19 at 01:12
  • I am seriously struggling to understand what you're looking for. Can you provide pseudocode? example `for item in li` `make this happen` – krflol Jun 25 '19 at 20:06
  • I know it is'nt easy to understand, please have a look at this [Link](https://stackoverflow.com/questions/53786287/qpainterpath-drawing-and-placering-items-along-multiple-paths), We need to draw some points inside rectangular shape, but my list Li tells for example (2,2) 2 layer of points already exist in top and bottom so just 4 points are already drawn, needs to draw or show intermediate points..... Please if you still do not follow what is going on, I would like to draw and explain more on the topic. – Pavel.D Jun 25 '19 at 20:23
  • what is the significance of numbers inside the li parameter, during your explanations I can't see what these numbers control – Tarun Lalwani Jun 26 '19 at 08:58
  • They are important numbers which control how many points should have with c value as distance between them. Item 1 inside Li list tells how many point ( Coordinates ) would be on left side of line, vice versa item2 how many points should be on right side of line. – Pavel.D Jun 26 '19 at 09:36
  • 3
    Forgive me, but your question is *very* confusing, you should edit the question using more self explainatory variable names (not `a`, `b` and `c`, as they have different purposes) and ensure that your examples make more sense, as they don't. What happens if the `li` has different values (like in the last example), or different len()? According to your example, only the first iteration is considered, and the `item` is not even accounted for, while you say that you should only need layers that have not been painted yet. Please, check everything again, otherwise it will be very hard to help you. – musicamante Jun 26 '19 at 23:01

1 Answers1

1

I hope I understood the question right, I'm working only with examples provided in the text.

The main method is get_points(), which accepts parameters b, c, a, li as in question and returns list of computed values:

from itertools import cycle

def get_points(b, c, a, li):
    num_points_left, num_points_right = li

    final_left = [*range(0, num_points_left * c, c)]
    final_right = [*range(b, b - num_points_right * c, -c)][::-1]
    final_center = []
    points_left = a - (len(final_left) + len(final_right))

    if points_left > 0:
        step = (final_right[0] - final_left[-1]) // (points_left+1)
        final_center = [final_left[-1] + step*i for i in range(1, points_left+1)]
    elif points_left < 0:
        cycle_list = [lambda: final_left.pop() if len(final_left) > 1 else None,
                      lambda: final_right.pop(0) if len(final_right) > 1 else None]

        if len(final_left) > len(final_right):
            remove_cycle = cycle(cycle_list)
        else:
            remove_cycle = cycle(cycle_list[::-1])

        while len(final_left) + len(final_right) > a:
            next(remove_cycle)()

    return final_left + final_center + final_right

def test(b, c, a, li, expected):
    print('Testing parameters:', b, c, a, li)
    print('Expected:', expected)
    returned = get_points(b, c, a, li)
    print('Returned:', returned)

    if returned == expected:
        print('* PASSED! *')
    else:
        print('!!! Fail !!!')

test(400, 25, 5 , [2,2], [ 0, 25, 200, 375, 400])
test(200, 30, 3 , [1,1], [0, 100 ,200])
test(300, 35, 4 , [2,2], [ 0, 35, 265, 300])
test(350, 40, 3 , [4,2], [ 0, 40, 350])

Prints:

Testing parameters: 400 25 5 [2, 2]
Expected: [0, 25, 200, 375, 400]
Returned: [0, 25, 200, 375, 400]
* PASSED! *
Testing parameters: 200 30 3 [1, 1]
Expected: [0, 100, 200]
Returned: [0, 100, 200]
* PASSED! *
Testing parameters: 300 35 4 [2, 2]
Expected: [0, 35, 265, 300]
Returned: [0, 35, 265, 300]
* PASSED! *
Testing parameters: 350 40 3 [4, 2]
Expected: [0, 40, 350]
Returned: [0, 40, 350]
* PASSED! *
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
  • 1
    You understood the question, your solution and answer is perfect and it is exactly what I'm looking for! I've tested some random value with a and li, it works magnificent, but I have to understand your algorithm and structure of `get_points`. Thanks a lot. – Pavel.D Jun 27 '19 at 20:09