Explain the difference in this while loop please - while-loop

Example:
x = 0
while x <= 10:
x += 2
print(x)
Results for this will be 0, 2, 4, 6, 8 , 10
If I switch the postion of print(x) and x += 2. The results will be 2, 4, 6, 8, 10, 12.
Please explain to me the thought process for this.
Thanks

I suppose this is Python. Basically the code will get executed in the order it is written. I suggest you to take a sheet of paper and follow the lines of code, trying to figure out what happens and what is the value of your variable at each step. The output will be the values that your variable had when it got printed with the print function.

Related

How can I use IF and ELSE IF in looping and display 2 statements in GAMS?

I am a beginner level in this program. I try to improve this loop according to this condition. The details are as follows:
When CUTI(k) = CUTI(k)-4 then,
1)If the result shows this CUTI(k) value greater than 0, then print this CUTI(k) value.
2)If the result shows CUTI(k) value less than 0, then print this CUTI(k) value is added 12 with showing a word "*" after the number in display, e.g. 10*, 9*
I am not sure this loop is correct and enough to add this condition. Look forward to seeing your recoomendation. :)
set k /1*20/;
parameter
CUTI(k)/1 6, 2 2, 3 8, 4 5, 5 1, 6 3, 7 7, 8 8, 9 6, 10 8,11 1, 12 2, 13 4, 14 7,
15 5, 16 2, 17 8, 18 9, 19 2, 20 10/;
loop(k,
if(CUTI(k)-4 > 0,
CUTI(k) = CUTI(k)-4;
else
CUTI(k) = (CUTI(k)-4)+12 ;
)
);
display CUTI;
Your logic looks correct. However, instead of the loop/if/else you could simplify this to one assignment:
CUTI(k) = CUTI(k)-4+12$(CUTI(k)<=4);
However, modifying the display statement by adding a * to some elements is not possible. If you need to distinguish the cases in such a statement, you might assign the values to two different parameters and display them individually.

is there efficient way for pandas to get tail rows with a condition

I want to get tail rows with a condition
For example:
I want to get all negative tail rows from a column 'A' like:
test = pd.DataFrame({'A':[-8, -9, -10, 1, 2, 3, 0, -1,-2,-3]})
I expect a 'method' to get new frame like:
A
0 -1
1 -2
2 -3
note that, it is not certain of how many 'negative' numbers are in the tail. So I can not run test.tail(3)
It looks like the pandas provided 'tail()' function can only run with a given number.
But my input data frame might be too large that I dont want run a simple loop to check one by one
Is there a smart way to do that?
Is this what you wanted?
test = pd.DataFrame({'A':[-8, -9, -10, 1, 2, 3, 0, -1,-2,-3]})
test = test.iloc[::-1]
test.loc[test.index.max():test[test['A'].ge(0)].index[0]+1]
Output:
A
9 -3
8 -2
7 -1
edit, if you want to get it back into the original order:
test.loc[test.index.max():test[test['A'].ge(0)].index[0]+1].iloc[::-1]
A
7 -1
8 -2
9 -3
Optional also .reset_index(drop=True) if you need a index starting at 0.
What's the tail for? It seems like you just need the negative numbers
test.query("A < 0")
Update: Find where sign changes, split the array and choose last one
split_points = (test.A.shift(1)<0) == (test.A<0)
np.split(test, split_points.loc[lambda x: x==False].index.tolist())[-1]
Output:
A
7 -1
8 -2
9 -3
Just share a picture of performance comparing above two given answers
Thansk Patry and Macro
I improved my above test, and did another round test, as I feel the old 'testing sample' size was too small,and afaid the %%time measurement might not accurate.
My new test uses a very big head numbers with size of 10000000 and tail with 3 negative numbers
so the new test can prove how the whole data frame size impact the over all performance.
code is like bellow:
%%time
arr = np.arange(1,10000000,1)
arr = np.concatenate((arr, [-2,-3,-4]))
test = pd.DataFrame({'A':arr})
test = test.iloc[::-1]
test.loc[test.index.max():test[test['A'].ge(0)].index[0]+1].iloc[::-1]
%%time
arr = np.arange(1,10000000,1)
arr = np.concatenate((arr, [-2,-3,-4]))
test = pd.DataFrame({'A':arr})
split_points = (test.A.shift(1)<0) == (test.A<0)
np.split(test, split_points.loc[lambda x: x==False].index.tolist())[-1]
due to system impacts, I tested 10 times, the above 2 methods are very much performs the similar. In about 50% cases Patryk's code even performs faster
Check out this image bellow

How do I return the sum of array with exceptions by using a while loop in a function?

Python beginner here.
I already have the solution to the question but I'm not understanding why the "add" variable in the solution plays a role of creating exceptions to remove numbers between 6 and 9. I already tried Python Tutor but still not understanding. Many thanks in advance!
QUESTION: Return the sum of the numbers in the array, except ignore sections of numbers starting with a 6 and extending to the next 9 (every 6 will be followed by at least one 9). Return 0 for no numbers.
Sample Solution code
def summer_69(arr):
total = 0
add = True
for num in arr:
while add:
if num != 6:
total += num
break
else:
add = False
while not add:
if num != 9:
break
else:
add = True
break
return total
Sample answers:
summer_69([1, 3, 5]) --> 9
summer_69([4, 5, 6, 7, 8, 9]) --> 9
summer_69([2, 1, 6, 9, 11]) --> 14
You can think of the variable "add" as a flag. I think that might be a better name for this variable in this instance.
It is only being used to tell if you have run into a 6 within the sequence of numbers in the array, then once it has been set it goes through an arbitrary amount of numbers in the array until it gets a 9 and then it resets the flag.
It may help to rename the variable "add" as "flag". Have your new variable "flag" default to False and then if you run into a 6 set "flag" to true. Once the flag is on do not add any trailing numbers in the sequence until you run into the number 9 then reset to false.
Perhaps that will help the readability. Naming variables is the hardest part of programming.

How do i convert an integer to an index in an "if" function?

My first question on this forum and im completely new to programming, so apologies if i do something wrong.
So im trying to program something to do a collatz sequense on a number i put in. To do that i have to check if the number i put in is even or odd. The easy fix would be to use the built in % 2 function but i want to do it "dirty" to learn better.
So my plan was to check if the last number in said input number is in the list (0, 2, 4, 6, 8) since an even number ends on those and is odd otherwise. Problem is how to check the very last index in the number to see if its in that list. I tried the following code
def Collatz(input_number):
input_number_num = int(input_number)
lenght = len(input_number_num)
position = lenght - 1
if [position] in input_number_num is in (0, 2, 4, 6, 8)
return (input_number_num / 2)
else:
return (input_number_num * 3 + 1)
This gives me a syntax error, im guessing since it reads [lenght] as an tuple rather than the index.
You could convert the number to a string and then use the -1 index to extract the last character:
if input_number[-1] in ('0', '2', '4', '6', '8'):
But to be completely honest, I can't see any advantage of doing this over just using % 2.

Step through range in D

Is there a way to create a step in D ranges?
For example, in python,
range(1, 10, 2)
gives me
[1, 3, 5, 7, 9]
all odds within 1 .. 10
Is there a way to do this in D using foreach?
foreach(x; 1 .. 10) {
}
I know I can use iota(start, end, step), but I also want to add an int to the very beginning and I don't know how to convert type Result to an int.
chain([2],iota(3,16,2));
chain concatenates ranges lazily
or you can go the other way around with filter!q{a==2||a&1}(iota(2,16));