Count the number of elements within a set of ranges - python

I am facing trouble on writing a function that takes 2 arguments (values, dividers) as a list and returns the number of elements in each range (determined by numbers in dividers) as one list. Elements that are equal to one of the dividers should be counted in the bin below.
I used if and elif to sort the numbers, which is sort of giving me the right idea. However, I am struggling on how to apply the fact 'number of bins = number of dividers + 1'
def histogram(values, dividers):
count1 = 0
count2 = 0
count3 = 0
index = 0
for index in range(len(values)):
if values[index] <= min(dividers):
count1 = count1 + 1
elif min(dividers) < values[index] <= min(dividers):
count2 = count2 + 1
elif values[index] > max(dividers):
count3 = count3 + 1
index = index + 1
print("Number of elements in each bin is ", [count1, count2, count3])
When I run the argument ([1,...,10], [2,5,7]) for instance, the answer should be [2,3,2,3] because the number of elements in range below 2, 2~5 (not including 5), 5~7 (not including 7) and above 7 is 2,3,2,3 respectively. However at the moment, I am getting the output [2,5,3].
P.S. My aim is writing the function without using numpy.histogram or any matplotlib related stuff

It's not the most efficient implementation, but it does not assume that values is sorted (only that dividers is):
def histogram(values, dividers):
bins = [0]*(len(dividers)+1)
extended_dividers = [-float('inf')]+dividers+[float('inf')]
for idx, divider in enumerate(extended_dividers[:-1]):
bins[idx] = len([v for v in values if divider<v<=extended_dividers[idx+1]])
return bins
Also, shouldn't the output in your example be 1,2,3,4?

Related

Function in getting the less than equal in the list and removing the duplicates

I need to count how many less than or equal numbers in the list and disregarding the duplicates.
def getVal(prices = [5,5,10], money = 5):
count = 0
for i in prices:
if money >= i and money == i:
count += 1
return count
the output of this code is:
2
How can I get the output of 1.
Convert your list into a set, and all the duplicate will be removed automatically:
def getVal(prices = [5,5,10], money = 5):
count = 0
for i in set(prices): # Add set() around the list to convert
if money >= i:
count += 1
return count
print(getVal())
Output:
1
One liner?
def getVal(prices, money):
return sum(i <= money for i in set(prices))
print(getVal([5, 5, 10], 5))
Whenever you come across avoiding duplicates, the answer is always a set.

How can I count how many numbers can be fitted within particular number?

Example 1:
save([4,4,4,3,3], 12) -> 3
# 4+4+4 <= 12, but 4+4+4+3 > 12
Example 2:
save([4,4,4,3,3], 11) -> 2
# 4+4 <= 11, but 4+4+4 > 11
First of all I'm noob yet, but here is my "code" lol.
def save(sizes, hd):
sum = 0
for i in sizes:
sum = sum + i
if sum <= hd:
a = (str(sum))
print(a)
save([4,4,4,3,3], 12)
Output of this code is:
4
8
12
It would be correct if I could count length of those numbers, but I tried many ways and still couldnt found(
Thanks for helping!
You need the enumerate() function:
def save(sizes, hd):
summm = 0
for index,value in enumerate(sizes,1): # start counting at 1
summm += value
if summm <= hd:
print(summm, index) # or simply print index alone
save([4,4,4,3,3], 12)
Outputs:
12 3 # first number is the sum, second amount of numbers you added (aka 1-based index)
You can use for i in range(len(sizes)) . I think it's the fastest solution, but I'm sure it doesn't matter.
def save(sizes, hd):
sum = 0
for i in range(len(sizes)): # i values are 0,1,2,...,len(sizes)-1
sum += sizes[i] # add i-th sizes element to sum
if sum <= hd: # check if we can print answer
print(i + 1) # because i starts from 0
else: # if we can't print, we should exit cycle
break # we can use return instead
By the way, you don't need to do anything like this, because 'print()' function converts all arguments to str()
a = str(sum)
print(a)
I hope, you has learned something new!
Try this one:
def save(sizes, hd):
sum = 0
new_list = []
for i in sizes:
sum += i
new_list.append(i)
if sum >= hd:
print(new_list)
return len(new_list)
print(save([4,4,4,3,3], 12))
#print(new_list) => [4, 4, 4]
#return len(new_list) => 3
If you build a list with the cumulative sum of your sorted numbers, the position of the target value will correspond to the maximum count of numbers that will fit within your target:
from bisect import bisect_right
from itertools import accumulate
numbers = [4,4,4,3,3]
target = 12
maxCount = bisect_right(list(accumulate(sorted(numbers))),target)
print(maxCount) # 3
The bisect module provides efficient search for an index in a sorted list (bisect_right). The itertools module provides a function (accumulate) to obtain the cumulative sum of numbers in a list
I changed your code around a bit to keep it simple:
def save(sizes, hd):
size_list = [] #instead of an int, let's use a list object to hold values
for size in sizes:
size_list.append(i) # add the size to the list
if sum(size_list) <= hd: # check if sum of all values in list is <= hd
return len(size_list) # return the number of sizes inside of list
hope this helps!

I want to find the sum of the number which i have

I have some code where I must find the multiples of number 3 and then summarize them
I have done the first job, I mean I found all the multiples of number 3 with for loop but I can't summarize all the numbers which I found.
I have tried so many times and tried to find the solution on google, but could not find
x = 3
for number in range(1000):
if number%x == 0:
print(number)
I need now the sum of all the numbers which indicates on this code, when you run this code you can see that there is publishing only the numbers that can divide by 3 now I need the sum of them
It's easier than you think:
sum(range(0, 1000, 3))
Explanation:
range is defined as such: range([start], end[, step]) so range(0, 1000, 3) means go from 0 to 1000 in steps of 3
The sum function will sum over any iterable (which includes range)
You need a variable to hold the sum (If you are in learning stage):
x = 3
total = 0
for number in range(1000):
if number % x == 0:
print(number)
total += number # equivalent to: total = total + number
print(total)
Edit:
To answer your comment use condition or condition:
x = 3
y = 5
total = 0
for number in range(10):
if number % x == 0 or number % y == 0:
print(number)
total += number # equivalent to: total = total + number
print(total)
You could create a result variable to which you can keep adding:
result = 0
x = 3
for number in range(1000):
if number%x == 0:
result += number
print(result)
The best way is using filter and sum:
# any iterable variable
iterable_var = range(100)
res = sum(filter(lambda x: x % 3 == 0, iterable_var), 0)

Largest Adjacent Numbers- Values Incrementing Incorrectly

I am writing this program to find the 13 adjacent digits in this number that, when added together, have the largest sum. When I run it, however, the b value does not start at 12; it starts at some obscenely high number and I cannot figure out why. Any idea why my a and b values are not incrementing correctly?
num = "731671765313306249192251196744265747423553491949349698352031277450632623957831801698480186947885184385861560789112949495459501737958331952853208805511125069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"
a = 0
b = 12
greatest = 0
while b != len(str(num)):
num = str(num)
newNum = num[a:b]
total = 0
for num in newNum:
num = int(num)
total += num
if total > greatest:
greatest = total
a+=1
b+=1
print(b)
print(greatest)
The main issue is that you are reusing num in the inner loop, which renders the "original" num wrong after the first run.
Additionally, if you want a 13 digits run-in, you'd better start with b = 13
And furthermore, there is no need for str(num) since it is already a string, and no need to change b along the program. You can also replace the inner loop with a sum upon map.
Here is what it should look like after these changes:
num = "731671765313306249192251196744265747423553491949349698352031277450632623957831801698480186947885184385861560789112949495459501737958331952853208805511125069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"
index = 0
run_in = 13
greatest = 0
while index + run_in < len(num):
num_slice = num[index: index + run_in]
slice_sum = sum(map(int, num_slice))
if slice_sum > greatest:
greatest = slice_sum
index += 1
print(greatest)
If you are into super functions, you can create the same effect with a list comprehension and a max closure, iterating all possible indexes (until the length of the number minus the run in):
greatest = max(sum(map(int, num[index: index + run_in])) for index in range(len(num) - run_in))
def largest(num, k):
num = str(num)
if len(num) < k: raise ValueError("Need a number with at least {} digits".format(k))
currsum = sum(int(i) for i in num[:k])
answer = currsum, 0
i = k+1
while i < len(num):
currsum -= int(num[i-k])
currsum += int(num[i])
if currsum > answer[0]: answer = currsum, i
i += 1
return answer
total, ind = largest(myNum, 13)
print("The maximum sum of digits is {}, starting at index {}".format(total, ind))

Difference between these python code samples?

I'm a python beginner and I'm trying to figure out the following below two python code samples. Both code looks same but printing a different result. The main function of the code is divisor summation.
CODE 1:
def divisor_sum(n):
no_div = 0
tot = int(n / 2) + 1
for i in range(1,tot):
if n % i == 0:
no_div += 1
print no_div
CODE 2:
def divisor2(m):
max_div = int(m / 2) + 1
val = 0
for x in range(1, max_div):
if m % x == 0:
val += x
print val
when calling the function?
divisor_sum(6)
divisor2(6)
Code ouput:
3
6
How it is producing two different results when both code samples are same?
Not exactly the same code:
CODE 1:
no_div += 1
CODE 2:
val += x
The first variant increments by 1 when a divisor is encountered:
no_div += 1
The second variant increments by the divisor:
val += x
This means that the first variant counts the number of divisors. The second variant sums the values of the divisors.
The divisors of 6 are 1, 2 and 3. So, there are a total of 3 divisors whose values sum to 6.
Code in first function i.e divisor_sum() will be giving you the count of divisors of a number (then name of function is misleading). On the other hand code in the second function i.e divisor2() will give you sum of all the divisors of a number.
both function has different code :
divisor_sum() has : "no_div += 1 " that means increment no_div by 1
divisor2() has :"val += x" which means increment the value of val by x i.e if x=2 then val will become val+2.

Categories

Resources