I don't understand how this code is working - python

Is this code correct?
def bubbleSort(arr):
sorted_arr = False
for i in range(len(arr)-1):
for j in range(len(arr)-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
sorted_arr = False
if sorted_arr:
print(bool(sorted_arr))
break
return arr
it is sorting the array, so I am assuming it's correct, however I don't understand how the second if block is working.
In the loop, each time i swap, the boolean value is set to False right? so in an already sorted array, what will be the value of sorted_arr? In the code it's True, otherwise it won't really enter the second if block, but why will the value change to True when it's intially set to False, and i'm not manually changing it anywhere?
(This is my primary understanding of how the code is working, i'm failing to grasp what is actually happening and so I am very confused. I apologize if my question isn't clear)

There is a small error in the code. The sorted_arr variable should be set to True before the second for loop. The only impact of this error is that the code will continue going through elements (and do nothing) even when the list is fully sorted.
So the code works but its optimization doesn't (i.e. it doesn't stop as soon as it reaches a sorted state).

Related

can't quite figure out what's not working (checkio excersise "Even the Last")

You are given an array of integers. You should find the sum of the integers with even indexes (0th, 2nd, 4th...). Then multiply this summed number and the final element of the array together. Don't forget that the first element has an index of 0.
For an empty array, the result will always be 0 (zero).
Input: A list of integers.
Output: The number as an integer.
Precondition: 0 ≤ len(array) ≤ 20
all(isinstance(x, int) for x in array)
all(-100 < x < 100 for x in array
result = 0
if array:
for element in array:
i = array.index(element)
if i%2 == 0:
result += element
else:
pass
else:
return 0
return result
Last_digit = array[-1]
final_result = result*Last_digit
return final_result
print(final_result)```
I've figured out the problem, that you've shared the array you're having problem with. Since you have this array :
[-37,-36,-19,-99,29,20,3,-7,-64,84,36,62,26,-76,55,-24,84,49,-65,41]
If you notice here, 84 appears twice, first at index 9 and then 16. The method you're using to get index of elements, .index returns the index of the first instance the element is found in the list.Therefore for the value of 84, the index is taken as 9 and not 16 which is an odd value, this does not add 84 to your sum. You should rather use enumerate for your code:
for idx, element in enumerate(array):
if idx %2 == 0:
result += element
First, I recommend reading the stackexchange guides on posting a well-formed question. You need to state what your goal is, what you've tried, what errors get thrown, and what the output should look like -- along with code examples and a minimal reproducible example as needed.
However, I'll help you out anyway.
You have a dangling return at line 11:
else:
return 0
return result
This makes no sense, as you've already returned 0. This is also apparently a snippet from a function, no? Post the whole function. But based on the instructions, you could try this:
import random
array = random.sample(range(-100, 100), 20)
def etl_func(arr):
arrsum = 0
for i, val in enumerate(arr):
if i%2 == 0: arrsum += val
return (arrsum * arr[-1])
answer = etl_func(array)
print(answer)
Note that importing random and using array = random.sample(range(-100, 100), 20) are not necessary if you're already GIVEN an array to work with. They're included here just as an example.
Also note that it's unnecessary to use an else: pass. If the condition evaluates to true (i.e. i%2 == 0), the if block will be executed. If i%2 != 0, the loop will short circuit automatically and move to the next iteration. Adding else: pass is like telling someone sitting in your chair to sit in your chair. You're telling the program to do what it's already going to do anyway. There's nothing necessarily wrong with including the else: pass, if it really want to... but it's just adding lines of meaningless code, which nobody wants to deal with.
EDIT: I don't know whether you were supposed to write a function or just some code (back to the "ask a well-formed question" issue...), so I went with a function. It should be trivial to turn the function into just plain code -- but you want to get into the habit of writing good functions for reusability and modularity. Makes everything run more smoothly and elegantly, and makes troubleshooting much easier.
This function also works for the array mentioned in the comments to your original post.
In addition, if you need a direct replacement for your code (rather than a function... I'm not familiar with checkio or how your answers are supposed to be formatted), and you already have the array of integers stored in the variable array, try this:
arrsum = 0
for i, val in enumerate(array):
if i%2 == 0: arrsum += val
print(arrsum * array[-1])
Since your question didn't say anything about using or defining functions, return statements shouldn't appear anywhere. There's nothing to return unless you're writing a function.

Why does my variable determining an item in a list become out of range?

So, I'm working on a function that will take a data list, and make a new list with items that repeat over a given number removed. So far, I have this while loop in the function
def solution(data, n):
timesRepeated = n
lengthData = data.__len__()
j = 0
while (j <= lengthData):
num = data[j]
if (check(data, num, n)):
print("Thisimes")
data = (list(filter((num).__ne__, data)))
j = 0
lengthData = data.__len__()
if (j == lengthData):
break
j += 1
The check() function just checks if num appears in the list more than n times and returns True if so. It's working as intended, I'm just missing something in the while loop
So, this is for the Google foobar test, so I don't want a solution to the function, but I just want to know why my j variable goes out of range of data. I keep getting this error: "IndexError: list index out of range" with this function run: solution([1, 2, 3], 0). If anyone could help an aspiring pythonista, it would be appreciated.
Edit: Thanks for the help, looking back on it, I realized my errors. Didn't know that I could just use <, thanks. Also, I just googled the 'data.len()' because I was unfamiliar with list attributes, so I'll replace that. The second if, I'll remove. The intended output would be nothing, since all of the items occur more than 0. I also realized that the 'num = data[j]' wouldn't be accurate since the length changes every iteration. Thanks for the feedback, I'll make those changes and answer this if it works
j <= lengthData will let j reach a value beyond the last index in data which is lengthData-1 because Python list indexes are zero based.
Use while j < lengthData: instead
Ok, so I think I figured out why the num variable kept going out of range. Since I would be removing items, the order of those items would change. Therefore, j would become higher the more iterations the while loop would run, so with the data being [1,2,3] and the n being 0, l would always be higher than 0 which would be the end result of the while loop. Thanks for all the help and suggestions. My work is not done yet, but at least this problem is. Have a good day everyone
Edit: Nevermind, Barmar and Alain T had it right, it was due to the <= not being <. Thanks again

make a WHILE contition while with a string

How could I do litteraly 1000 'or' conditions im my while, for image processing.
The goal here is to do this :
while (img0[i,j] != NOIR0).all() or (img0[i,j] != NOIR1) or (img0[i,j] != NOIR2) ... :
and this goes on to NOIR999, with NOIRx being different constants.
I thought to code a for that fulfil a string, but I can't put it as a condition in the while.
Could someone help me please ? :)
for the n you can do this:
while n<=999:
print(n)
n = n+1
This is the most basic layout of a while loop.
A while loop continues on forever until a condition is met.
If you want a for loop:
for n in range(0, 1000):
print(n)
What you are looking for is the built-in any() function.
This function receives an iterator and will return True if any of the items is evaluated to True, else it will return False.
The good thing with that is short-circuiting - whenever a True value is encountered, the function will not continue with the iterable.
while any((img0[i, j] != f"NOIR{n}").all() for n in range(1000)):

Explain the bubble sort algorithm?

I'm trying to learn more about algorithms and i'm looking into the bubble sort algorithm. I found the script for it on github but I cant really understand it. I'm sorta new to python so can someone explain to me what's going on in this script.
from __future__ import print_function
def bubble_sort(arr):
n = len(arr)
# Traverse through all array elements
for i in range(n):
# Last i elements are already in place
for j in range(0, n-i-1):
# traverse the array from 0 to n-i-1
# Swap if the element found is greater
# than the next element
if arr[j] > arr[j+1] :
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
if __name__ == '__main__':
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
user_input = raw_input('Enter numbers separated by a comma:').strip()
unsorted = [int(item) for item in user_input.split(',')]
print(*bubble_sort(unsorted), sep=',')
Visualize the array as a vertical list of numbers, with the first element (index 0) on the bottom, and the last element (index n-1) at the top. The idea of bubble sort is that numbers "bubble up" to the top, into the place where they belong.
For example, [2,3,1] would first look at 2 and 3, and not do anything because they're already in order. Then it would look at 3 and 1, swapping them since 3>1 and getting [2,1,3]. Then we repeat by looking at 2 and 1, swapping them since 2>1 to get [1,2,3], which is in order.
The idea is that "3" and then "2" bubbled up to the correct position.
Note that after the 3 bubbled up, we don't have to compare 2 and 3, because we know the last element is already higher than everything before it. In general, after i iterations of bubble sort, there's no need to compare the last i elements.
from __future__ import print_function Here we are essentially bringing in code that was written by somebody else, so that we may use it.
def bubble_sort(arr): This is is a function definition. A function definition is preceded by the keyword def. Following that is the function's name. In this case it is called bubble_sort. What we have in the parenthesis are called parameters. A parameter is something we give to a function, so that the function may use it, e.g., multiply the parameter by a number, sort the list, or send some information to a server.
Since we are on the topic of functions, I would suggest looking up process abstraction.
arr Here I am referring to arr within the function's definition. It is short for array, which is a list type. In python we could define an array like so fruits = ["banana", "apple", "orange"]. Arrays are useful for grouping together like pieces of information, and in python I believe this are actually known as a list type. So, conceptually, it may be easier to imagine a list rather than the more esoteric array.
n = len(arr) We are literally assigning the length of the array into the variable n. This is probably shorthand for number of elements. len(arr) is a function that takes an array/list, and returns its length. Similarly, one could call print len(arr) or simply len(arr).
for j in range(0, n-i-1): This is a bit more complicated since it requires an understanding of the algorithm in play, i.e., bubblesort. I won't explain how bubblesort works since there is probably a ton of videos online, but I will explain the bit within the parenthesis.
(0, n-i-1) We want to make comparisons between our current element and the ones preceding it. The ones preceding our current element are greater than the current element. This means if we are at element i, then we have no need to compare elements from i to n, inclusive. We subtract i from n, which leaves us with elements 0 through i. We don't need to compare i to itself, so we subtract an additional 1. This is due to j cycling through the array, and being potentially the same as i.
if arr[j] > arr[j+1] : This is a conditional statement, also known as a branching statement, or an if-statement. The condition, arr[j] > arr[j+1], is true with the element at position j is greater than the one at j+1.
arr[j], arr[j+1] = arr[j+1], arr[j] I think this is shorthand for swapping. A simple swap is shown below.
temp = arr[j]
arr[j] = arr[j+1]
arr[j+1] = temp
return arr Returns the sorted array.
The last bit I am not familiar with since I don't use python much. Perhaps this could be some research for you.
Hopefully this helps.

Recursive Function in Python adding Odd Values in List

My task is to create a recursive function in Python that takes a list and a value of 0 as its inputs and then adds up all of the odd numbers on the list and returns that value. Below is the code that I have and it keeps returning that the list index is out of range. No matter what I do I can not get it to work.
def addodds2(x,y):
total=0
a=x[y]
while y<len(x):
if a%2!=0:
total+=a
return(addodds2(x,y+1))
else:
return(addodds2(x,y+1))
return(total)
print(addodds2([3,2,4,7,2,4,1,3,2],0))
Since you are trying to solve this recursively, I don't think you want that while loop.
When you are trying to solve a problem recursively, you need two parts: you need a part that does some of the work, and you need a part that handles reaching the end of the work. This is the "basis case".
Often when solving problems like this, if you have a zero-length list you hit the basis case immediately. What should be the result for a zero-length list? I'd say 0.
So, here's the basic outline of a function to add together all the numbers in a list:
Check the length, and if you are already at the end or after the end, return 0. Otherwise, return the current item added to a recursive call (with the index value incremented).
Get that working, and then modify it so it only adds the odd values.
P.S. This seems like homework, so I didn't want to just give you the code. It's easier to remember this stuff if you actually figure it out yourself. Good luck!
Your code should be (the comments explain my corrections):
def addodds2(x,y):
total=0
if y<len(x): #you don't need a while there
a=x[y] #you have to do this operation if y<len(x), otherwise you would get the index error you are getting
if a%2!=0:
total+=a
return total+addodds2(x,y+1) #you have to sum the current total to the result returned by the addodds2() function (otherwise you would got 0 as the final result)
return total
print(addodds2([3,2,4,7,2,4,1,3,2],0))
while y<len(x)
So the last y which is smaller than len(x) is y = len(x) - 1, so it’s the very last item of the list.
addodds2(x,y+1)
Then you try to access the element after that item, which does not exist, so you get the IndexError.
This code can be very short and elegant:
def add_odds(lst, i=0):
try:
return (lst[i] if lst[i] % 2 == 0 else 0) + add_odds(lst, i+1)
except IndexError:
return 0
Note that, in a truly functional style, you wouldn't keep track of an index either. In Python, it would be rather inefficient, though, but recursion isn't recommended in Python anyway.
def add_odds2(lst):
try:
return (lst[-1] if lst[-1] % 2 == 0 else 0) + add_odds2(lst[:-1])
except IndexError:
return 0
To make it work with any kind of sequence, you can do the following:
def add_odds3(it):
it = iter(it)
try:
value = next(it)
return (value if value % 2 == 0 else 0) + add_odds3(it)
except StopIteration:
return 0
It's much more efficient, though there's not much sense in using an iterator recursively...
I realize that little of this is relevant for your (educational) purposes, but I just wanted to show (all of) you some nice Python. :)

Categories

Resources