Program not showing all values in for loop - python

i have started learning python and i have problem.
I learn for loops and i am a little bit confused.
I tried this:
for i in range(0,12,3):
print(i)
Why program is not showing 12 value?
In other languages e.g java it works.
Anyone help?

The upper bound of range is non-inclusive. From the documentation:
For a positive step, the contents of a range r are determined by the formula r[i] = start + step*i where i >= 0 and r[i] < stop.
Read more here.
Java's equivalent:
IntStream.range(0, 12 / 3).map(x -> x * 3).forEach(System.out::print);
Also does not include the upper bound. This will also print 0 3 6 9, not 12.

The upper bound of a range is not included. The main advantage is that range(len()) "just works" without having to subtract 1. For example:
>>> x = 'abcd'
>>> for i in range(len(x)):
... print(i, x[i])
...
0 a
1 b
2 c
3 d

Related

4-Way MergeSort Challenge - Python

I'm trying to write a MergeSort function that splits the array into 4 arrays and not into 2 like the regular MergeSort..
I tried to follow the 2-way mergeSort and implement it to the 4-way but I keep getting stuck in recursive calls and I can't understand where's the problem..
I wrote a merge_sort_4 function that calls itself 4 times and merge4 function that should merge 4 arrays and not 2.
I know some people in my class solved it with 3 calls to the regular Merge function but I think it kinda misses the point of this challenge..
If the only way of solving it is by using the regular Merge please tell me, if not, please help me find the problem
Here's my code
def merge_sort_4(lst, start, end):
if start < end:
quarter1 = (start + end) // 4
quarter2 = (start + end) // 2
quarter3 = (end - quarter1 - 1)
merge_sort_4(lst, start, quarter1)
merge_sort_4(lst, quarter1 + 1, quarter2)
merge_sort_4(lst, quarter2 + 1, quarter3)
merge_sort_4(lst, quarter3 + 1, end)
merge4(lst, start, quarter1, quarter2, quarter3, end)
def merge4(lst, start, q1, q2, q3, end):
first_q_list = lst[start:q1 + 1]
sec_q_list = lst[q1 + 1:q2 + 1]
third_q_list = lst[q2 + 1:q3 + 1]
last_q_list = lst[q3 + 1:end + 1]
first_q_list.append(float('inf'))
sec_q_list.append(float('inf'))
third_q_list.append(float('inf'))
last_q_list.append(float('inf'))
i = 0 # first sublist index
j = 0 # sec sublist index
m = 0 # third sublist index
n = 0 # last sublist index
for k in range(start, end + 1):
if first_q_list[i] <= sec_q_list[j] and first_q_list[i] <= third_q_list[m] and first_q_list[i] <= last_q_list[
n]:
lst[k] = first_q_list[i]
i += 1
elif sec_q_list[j] <= third_q_list[m] and sec_q_list[j] <= last_q_list[n]:
lst[k] = sec_q_list[j]
j += 1
elif third_q_list[m] <= last_q_list[n]:
lst[k] = third_q_list[m]
m += 1
else:
lst[k] = last_q_list[n]
n += 1
thanks in advance for your help!
Okay, so I have some ideas about things that are probably wrong here, but you've not really given much indication of what help you need, so first I want to point you in the right direction for how to figure this out yourself.
Before you even write any code to go inside merge4 and merge_sort_4, can you describe what are their preconditions and postconditions? I.e., what do you require to be true before one of them is called, both about the state of the list and the arguments passed to it? What is its job? What does it guarantee to have done when it has finished? What values can start have, and what values can end have?
I'm hoping that you're going to describe some constraints such as that 0 <= start <= end < len(lst) for calling merge_sort_4 and that 0 <= start <= q1 <= q2 <= q3 <= end <= len(lst) for calling merge4, and that merge4 requires the four sublists to be sorted and will guarantee that the entire range from list index start to end is sorted.
Now - are those things actually true? Can you walk through the code with example values and see what would happen? Can you add assertions into the algorithm to catch the first time one of them isn't true? Can you test the pieces of the algorithm separately on small pieces of test data to see if they behave as you expect?
Try and see if you can figure it out on your own, but if not, here's one place I suggest you start looking...
...
...
I would expect that quarter1, quarter2 and quarter3 should all fall within the range of start to end but I think the calculations you have there might not be doing what you expect. Try some different values of start and end and see if you are surprised what comes out.
There is an issue with using sentinel values (float('inf')). Consider the case when the ends of multiple runs have been reached, for example when first_q_list[i] == sec_q_list[j] == float('inf'), in which case the float('inf') at first_q_list[i] is copied to lst[k] and i is incremented beyond the end of first_q_list[].
The code needs to check for reaching the end of a run each time it copies an element, and if so, drop down to a 3 way merge of the remaining runs. Later dropping to 2 way merge and then finally a copy of the rest of the one remaining run.
The code could be improved, consider the case where third_q_lst[] or last_q_lst[] has the smallest element, it takes 6 compares to get to those cases. By using nested if + else, this can be reduced to just 3 compares along any path to determine which run has the smallest element. Example for 3 way merge to find smallest of a, b, c, with only 2 compares for any of the 3 possible cases:
if(a <= b)
if(a <= c)
a is smallest
else
c is smallest
else
if(b <= c)
b is smallest
else
c is smallest
Link to java example of a 4 way top down hybrid merge sort + insertion sort (for small runs). I haven't bothered porting it to Python because Python is so slow, and due to Python being an interpretive language, 4 way merge sort would probably be slower in Python than 2 way (with a compiled language, 4 way is about 15% faster than 2 way).
How can I implement the Merge Sort algorithm with 4-way partition without the error ArrayIndexOutOfBoundsException?

loop numbers down and up and not using recursion in python

I have a small problem with my code. I can't seem to figure out how to do this. I can get it to work with two for loops. But in the exercise it says that i only can use one loop to get the result.
The code is supposed to execute this:
bounce2(4):
4
3
2
1
0
1
2
3
4
What I have come up with:
def bounce2(n):
for x in range(n,-1,-1):
print(x)
Which prints out 4,3,2,1,0
But now i dont know what to do..
I have tried different if statements such as:
def bounce2(n):
for x in range(n,-1,-1):
print(x)
if n == 0:
x = x + 1
print(x)
But they only print one integer because they are out of the loop.
Same thing goes if i try to make the if-statement inside the loop, then it prints out something like 433221100. I dont know how to get the numbers to switch places. The print statement should also be an integer and not a string. So i can't use replaced.
Really need help to figure out the logic. All help is appreciated.
So, a little bit of my thought process before showing you the code. Clearly there are nine lines, or more generally n * 2 + 1 lines. Because we need to count down to 0 and back up. That's how many times you need to call print.
Now, if you add line numbers to the expected output and think of it as a table describing a function f(i, n) where i is the line number, and n is the starting and ending value. what is f? Can you write down the formula? e.g.
i f(i, 4)
0 4
1 3
2 2
3 1
4 0
5 1
6 2
7 3
8 4
We can write down the basic structure of the code, we still don't know what f look like but assume we have it:
for i in range(2*n+1):
print f(i)
And, what is f? Now you need to be a little creative and maybe experiment a bit. What I did was to try basic arithmetic combinations of i and n to match f(i, n), and I quickly noticed that n - i works until we reach the second half of the output, which only differs by a - sign.
i f(i, 4) n - i
0 4 4
1 3 3
2 2 2
3 1 1
4 0 0
5 1 -1
6 2 -2
7 3 -3
8 4 -4
Soooo, take the absolute value of n - i or i - n, whatever.
def f(i, n):
return abs(n-i)
Here is what I believe to be a pretty elegant solution:
def bounce(n):
for x in range(-n, n+1):
print(abs(x))
Our loop goes from the negative of n to the positive of n, printing the absolute value.
Since you need to count n times downwards, and another n times upwards, and 1 comes from counting 0, instead of actually counting downwards and then upwards in two separate loops, we can use one loop to count upwards 2 * n + 1 times, which effectively is like counting towards n and then bouncing off n, so we can simply calculate the "distance" to n instead, which is the absolute value of n - x:
def bounce2(n):
for x in range(2 * n + 1):
print(abs(n - x))
so that bounce2(4) would output:
4
3
2
1
0
1
2
3
4
a very simple solution will be:
for i in range(n, -(n+1), -1):
print(abs(i))
this like mirroring numbers around some point.
in your case that point is zero and to have identical mirroring use abs
Try the below, have a list l with a element of str(n) iterate trough the range of n times 2, then check x is bigger than n+2 if it is add 1 to n, otherwise subtract 1 from n, both cases append to l, then at the end, do str.join to join '\n' (newline) with l:
def bounce2(n):
l=[str(n)]
for x in range(n*2):
if x>n+2:
n+=1
l.append(str(n))
else:
n-=1
l.append(str(n))
return '\n'.join(l)
print(bounce2(4))
Output:
4
3
2
1
0
1
2
3
4

What's the problem with my Python script?

I'm trying to use Python to solve my maths homework (you have a two digit number ab, and ab+ba=88) and my program doesn't work.
a=10
b=10
for i in range(100):
a+=1
for i in range(100):
b+=1
if int(str(a+b))+int(str(b+a))==88:
print((str(a+b))+"+"+str(b+a))
It gives the output of 44. This isn't the good answer, because a and b have to be different numbers, but I didn't code that restriction yet. More important, the code should find 26;62 and other solutions. How can I find all the solutions?
I know the answers, but I want to solve it in this way too.
If I understand correctly, you have a two digit number ab such that ab + ba = 88
Ex) For "ab" = 26 --> 26 + 62 = 88.
If that is the case, this is the solution I propose the solution:
for a in range(10): # Iterate over ten's place values [0 to 9]
for b in range(10): # Iterate over one's place values [0 to 9]
ab = str(a)+str(b) # Construct the string "ab"
if (int(ab) + int(ab[::-1]) == 88): # Test if ab + ba = 88
print(ab + " + " + ab[::-1]) # Print the successful value of ab
The logic is that you construct a string ab by combining the possible values of 0 to 10 in each of the ten's and one's place of the two digit number. Then, test if the integer value of ab and its reverse, ba, are equal to 88.
OUTPUT:
08 + 80
17 + 71
26 + 62
35 + 53
44 + 44
53 + 35
62 + 26
71 + 17
80 + 08
NOTE: This method uses a string from the get go in order to avoid the many calls to int(str()).
NOTE: In Python, the operator [::-1] returns the reverse of the string. Just a convenient trick!
You have a couple of logic problems here. The first is your loop control. You start with
a=10
for i in range(100):
a+=1
This will run a over the range 10 to 10+100. Now, for each value of a, you do:
b=10
...
for i in range(100):
b+=1
First of all, you've changed the value of i, which the outer loop is still trying to use. This is the first problem, the one that's killing your current program. Second, if you fix this by changing the loop index to j (for instance), then you will increment b 100*100 times, so it ends up at 10010.
On top of this, a and b are never individual digits! You've started each as a 2-digit number.
Instead, make two changes:
Put the values you actually want into the for loop.
Use strings, not integers, if that's what you're trying to do.
for a in "0123456789":
for b in "0123456789":
if int(a+b) + int(b+a) == 88:
This code makes 2-digit strings. Another way is to work with the single-digit integers, but then use algebra to make the 2-digit numbers:
if (10*a + b) + (10*b + a) == 88:
Finally, you can simplify the entire process by doing basic algebra on the above expression:
(10*a + b) + (10*b + a) == 88
11*a + 11*b == 88
a + b = 8
From here, you note simply that b = 8-a, and you can reduce your program to a single loop.
Let's walk through what your code does.
First you assign both a and b to be 10
a=10
b=10
Then you start a loop that will run 100 times, each time it runs it will increment a by one
for i in range(100):
a+=1
Then you start a nested loop which will run 100 times each time the outer loop runs once and increments b on each loop. It is important to note that because you have defined b outside of the scope of this loop, it will keep growing. The second time the outer loop runs, b is going to start at 110
What you need to know here is that python is a weakly typed language. Variables take on the same type as the data assigned to them. a and b are integers, so you can already perform mathematical operations on them. Also, there's no reason to typecast the same variable twice in one spot. you should write the if statement like this:
if a + b + b +a == 88:
You can see more easily now that all it is checking is if (a + b) * 2 is equal to 80
Finally you output your answer but, do to the commutative property of addition, you're always going to show the same sum + itself
print((str(a+b))+"+"+str(b+a))
What I would recommend doing here, besides cleaning up your if statement, is resetting b each time the outer loop runs. I'm also unclear why you've instantiated your variable to equal 10 but that's your business.
Try this:
a=10
for i in range(100):
b=10
a+=1
for i in range(100):
b+=1
if a+b == 88:
print((str(a))+"+"+str(b))
Use this code to understand:
a=10
b=10
for i in range(100):
a+=1
for i in range(100):
b+=1
if int(str(a+b))+int(str(b+a))==88:
print(a)
print(b)
print((str(a+b))+"+"+str(b+a))
break;
Output:
11
33
44+44
So:
A = 11
B = 33

Python gives me different outputs if I add a print() later on

I'm super new to programming and just wanted to make something to find the approximate value of x for the equation x^3 - 1 = x. I know that -2 is greater than 0 and -1 is less. My thought is that if I find the average and check if it's greater or less than 0, I can redefine a and b and repeat until I get an approximate value. I've been having a hard time getting it to act right though. For example if I run this block without the print(i), I'll get -1.5 which would be the average, but when I put a print(total) within the function equation(n) to see if it's working right, it doesn't even show me that and just outputs -8.881784197001252e-16. If I put print(i) at the end of the if/else possibilities, such as this, it prints 16 and then -8.881784197001252e-16. I'm using PyCharm CE.
Beyond this glitch, is my logic correct? By setting the placeholder to 1 it will run the while loop. The while loop will get a new value of n and run the function, compare it to 0, then reassign a or b depending on that comparison? Thanks in advance.
a = float(-2)
b = float(-1)
n = ((a+b)/2)
print(n)
def equation(n):
total = float((n - n**3 - 1))
return total
i = 1
while i != 0:
n = ((a + b) / 2)
if (equation(n)) > 0.0:
a = n
i = equation(n)
print(i)
else:
b = n
i = equation(n)
print(i)
Moving all of the equation x^3 - 1 = x to one side should give x^3 - 1 - x = 0 or x - x^3 + 1 = 0. You have a different equation in your function.
Another problem is that there is no intersection between the two equations between x=-2 and x=-1 (see here). You'll need to expand your window to x=2 before you'll see an intersection.
Something that often happens in numerical analysis (where you'll see this type of problem) is that rather than trying to find x that actually makes the equation give 0, we look for a value of x that produces below an acceptable level of error. Another approach is to test for while b - a > tol:
If we use all of this to tweak what you've got, you'll have
a = float(-2)
b = float(2)
tol = 0.001
def equation(n):
return float(n - n**3 + 1)
n = (a + b) / 2
iter = 0
while abs(equation(n) - 0) > tol and iter < 100:
iter+=1
if equation(n) > 0.0:
a = n
else:
b = n
n = (a + b) / 2
print(iter,a,b,equation(n))
Note: this works fine if you remove the floats and just do
a = -2
b = 2
#...etc
because python already recasts values as necessary. Try
>>> type(3)
<class 'int'>
>>> type(3.5)
<class 'float'>
>>> type(float(3))
<class 'float'>
>>> type(3/5)
<class 'float'>
so python will store the result as a float as soon as it is necessary.
The immediate problem is the limited precision of floats. If you print a and b after a hundred iterations, you get:
a, b = -1.324717957244746, -1.3247179572447458
print((a + b) / 2 # -1.3247179572447458, the same as b
So at some point, b never changes, which is why you get an infinite loop. If we evaluate equation at the average of a and b, you'll get -8.881784197001252e-16, the value you were always seeing.
But this will never converge to exactly zero because the solution is irrational, so even if you had infinite precision, equation would never equal zero.
The common way to resolve this issue is to avoid comparing floats:
if a == b # don't do this
if abs(a - b) < epsilon # do this, where epsilon is some small value
(Note: what you're describing is the bisection method, which is slower than higher order algorithms e.g. Newton's method, which you can use since you can get the derivative)

Project Euler using Python, Regarding definition of multiples

I started programming recently, my first language being python. I know just the basics of the language including conditionals, loops, range and some other functions.
I tried to solve project euler's problem 1 using python. The problem statement is as follows:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
Here's my solution:
z=0
for x in range(0,1000,1):
if type(x%3)==int or type(x%5)==int:
z=x+z
print z
The answer i get is 499500 which is wrong. I tried searching for an answer and found that replacing the third line of my solution:
if type(x%3)==int or type(x%5)==int
with
if x%3==0 or x%5==0
yields the correct answer which is 233168.
Why is my code wrong? So far as I'm aware, a multiple need not leave the remainder as zero. For instance, 255 is a multiple of 5. But 255%5 does not leave the remainder as zero. So how does the line if x%3==0 or x%5==0 correct the answer when in fact, it ignores the definition of multiples.
Or perhaps I have wrongly assumed what multiples are. Please help me.
Thank you.
The problem with your original code, is that Modulo operation with natural numbers always yields a natural number.
print type(4%3)
#print <type 'int'>
print type(4%3)==int
#print True
So, what you are doing is basically summing all numbers between 0 and 1000:
print sum(range(0,1000,1))
#prints 499500
Hope that helps
a is a multiple of b iff a = k b with k an integer. Then % is modulo, which is defined like that:
a % b = z iff a = k b + z with k (and z) integers (and 0 <= z < b)
Therefore if z= 0, then a = k b and a is a multiple of b.

Categories