Finding Avg of all 2-Digit in a list - python

I'm trying to find the avg of list but only when n >= 10 (two digit numbers, my original list is limited to 100).
Here's what I have right now:
# Calculate average of all two-digit numbers (10-99)
grade_list = [10, 11, 12, 13, 14, 15]
def calcAvg(grade_list):
while n > 10:
total = sum(grade_list)
n = total % len(grade_list)
print_list = n
return print_list
I get that I have to find the total sum of the list when n > 10 and then dividing by the length (only > 10, my original list has single digit elements, so I'd like to avoid them).
But when I run it, I get an error saying: local variable 'n' referenced before assignment
Any help on how to structure this function to achieve the end results (sum/total of only 2-digit elements = avg)
Thanks!

I'd either collect the good grades and use sum/len, or use the mean function:
>>> grade_list = [1, 2, 10, 11, 12, 13, 14, 15]
>>> good = [g for g in grade_list if g > 10]
>>> sum(good) / len(good)
13.0
>>> import statistics
>>> statistics.mean(g for g in grade_list if g > 10)
13.0

def calcAvg(grade_list):
my_list = []
total, count = 0,0
for n in grade_list:
if 10 <= n <= 99:
total += n
if not total:
return None
return total/count

Here is a clean way of doing it:
def calc_avg(lst):
filtered_lst = filter(lambda x: 10 < x < 100, lst)
return sum(filtered_lst) / len(filtered_lst)

So you should use a for loop instead of a while loop. Instead of having two for loops and making a new list, you could just account for the sum inside the first for loop. I demonstrate this below.
def calcAvg(grade_list):
sum = 0;
count = 0;
for n in grade_list:
if 10 <= n <= 99:
sum = sum + n
count = count + 1
return sum/count

I think you should manually go over the code step by step and try to understand what is wrong. Meanwhile this may give you some hints
# Calculate average of all two-digit numbers (10-99)
def calcAvg(alist):
count=total=0
for i in alist:
if 9 < i < 100:
total += i
count += 1
return total/count

Since Python 3.4 there is a statistics module.
So you just need to filter out numbers in range <10,100), for example with a list comprehension, and then pass this filtered list to the mean function. Simple as that.
from statistics import mean
numbers = [1, 20, 30, 50]
mean([n for n in numbers if n >= 10 and n < 100])
>>> 33.333333333333336

You could do this fairly simply with a list comprehension
>>> grades = [1, 2, 10, 11, 12, 13, 14, 15, 120, 122, 320]
>>> lst = [v for v in grades if 10 <= v < 100]
>>> sum(lst)/len(lst)
12

Related

How to find the lowest difference between two numbers from the given list in python using nested while loop?

num = [100, 10, 200, 25, 7, 20]
l = len(num)
i = 0
min = 0
while i < l:
j = i+1
while j < l:
ans = num[i] - num[j]
print(f'{num[i]} diff {num[j]} is {ans}')
j += 1
i += 1
The output should be the lowest difference which should be 3 for this problem.
I know how to get all the difference but I don't know how to filter out the smallest difference.
You may first sort it, and then loop through it for least difference.
num = [100, 10, 200, 25, 7, 20]
num.sort()
least_diff=None
for i in range(len(num)-1):
diff=abs(num[i]-num[i+1])
if not least_diff:
least_diff=diff
if diff<least_diff:
least_diff=diff
print(least_diff)
Output:
3
There's two issues that you probably need to deal with in finding the minimum difference using this technique:
retaining the minimum as you generate the individual differences
taking the absolute value of the difference (if that's what you want)
Couple of side notes: it is really confusing to use the single letter l as a variable name, given its resemblance to the digit 1. And min is a built-in function so using that as variable name, while totally legal, can also be confusing.
So, within your flow structure, and using just built-in facilities rather than libraries, you could write:
num = [100, 10, 200, 25, 7, 20]
sz = len(num)
i = 0
ans = abs(num[1]-num[0]) # initialize to a possible value
while i < sz:
j = i+1
while j < sz:
diff = abs(num[i] - num[j]) # take positive diff using abs built-in function
# print(f'{num[i]} diff {num[j]} is {diff}')
if diff < ans: # or could use min function or in-line-if
ans = diff
j += 1
i += 1

python version 3.6.3 Functions and lists

I am trying to run the following:
def count_small(numbers):
total = 0
for n in numbers:
if n < 10:
total = total + 1
return total
lotto = [4, 8, 15, 16, 23, 42]
small = count_small(lotto)
print(small)
Here I have defined a function 'count_small(numbers)'
it starts with a total of 0,
then checks each item in the list, to check that it is less than 10, if the item is less then 10, then 1 will be added to the total. I am running the function on the list 'lotto', as you can see 'lotto' has two numbers less than 10 '4' and '8' hence it should return 2, however, when I run the code it returns 1 instead.
Your return statement is inside the for-loop, so that the function is left after the first number.
def count_small(numbers):
total = 0
for n in numbers:
if n < 10:
total += 1
return total
When you use a generator expression, you can write this in one line:
def count_small(numbers):
return sum(n<10 for n in numbers)
Your indentation is incorrect. Place the return statement outside of your for loop.

Find Sum of list with condition

I am stuck at a problem.
I have a List L = [1,2,3,4,5,6,7,8,9]
I want to find the sum of elements in lists such that, if the sum exceeds's 25. I want to get the previous sum.
for eg. 1+2+3+4+5+6+7=28, 28>25. Therefore i want a final variable sum as 21.
i am doing it using for-if combination, but i don't want to use if . Is there a better way of doing this? below is my code.
L = [1,2,3,4,5,6,7,8,9]
summ = 0
for val in L:
summ+= val
if summ > 25:
summ-=val
I think what bothers you is the summ-=val part, not the if. And there is a one line solution with reduce.
>>> from functools import reduce
>>> L = [1,2,3,4,5,6,7,8,9]
>>> reduce(lambda x, y: x + y if x + y <= 25 else x, L)
21
https://docs.python.org/3/library/functools.html#functools.reduce
You can use a while loop:
L = [1,2,3,4,5,6,7,8,9]
i = 0
s = 0
while i < len(L) and s + L[i] < 25:
s += L[i]
i += 1
Using pandas, take the cumulative sum on a series consisting of the numbers in the list. Assign the value NaN to any any cumulative sum over max_value. Fill forward the result and convert back to a list of integers.
import pandas as pd
max_val = 25
a = range(1, 10)
s = pd.Series(a).cumsum()
s.loc[s > max_val] = np.nan
>>> s.ffill().astype(int).tolist()
[1, 3, 6, 10, 15, 21, 21, 21, 21]
How about integrating the condition into the mathematical expression:
L = [1,2,3,4,5,6,7,8,9]
summ = 0
for val in L:
summ = summ+val*(summ+val <= 25)

Most Divisors in Python

I want to write a function called find_integer_with_most_divisors that accepts a list of integers and returns the integer from the list that has the most divisors. In case of a tie, return the first item that has the most divisors.
For example:
if the list is:
[8, 12, 18, 6]
In this list, 8 has four divisors which are: [1,2,4,8] ; 12 has six divisors which are: [1,2,3,4,6,12]; 18 has six divisors which are: [1,2,3,6,9,18] ; and 6 has four divisors which are: [1,2,3,6]. Notice that both 12 and 18 are tied for maximum number of divisors (both have 6 divisors). My function should return the first item with maximum number of divisors; so it should return:
12
Now I wrote bellow code for find division of each number, that are in list. Can any body help me to continue this function.
Thanks.
def find_integer_with_most_divisors(input_list):
for i in input_list:
my_list = []
for x in range(1,i+1):
if i % x == 0:
my_list.append(i)
You can create a list of the number of divisors in your function and then match the highest number in that list to your original list:
def find_integer_with_most_divisors(input_list):
nr_divisors = []
for i in input_list:
my_list = []
for x in range(1, i+1):
if i % x == 0:
my_list.append(x)
nr_divisors.append(len(my_list))
return input_list[nr_divisors.index(max(nr_divisors))]
a = [8, 12, 18, 6]
print find_integer_with_most_divisors(a)
returns
12
Why not just use max with the number of divisors as key?
>>> max([8, 12, 18, 6], key=lambda n: sum(n%d == 0 for d in range(1, n+1)))
12
All you need to do is keep track of the number with the most so far. I also changed your creation of my_list to something a little simpler:
def find_integer_with_most_divisors(input_list):
winning_list = []
winning_number = None
for i in input_list:
my_list = [x for x in range(1, i + 1) if i % x == 0]
if len(my_list) > len(winning_list):
winning_list = my_list
winning_number = i
return winning_number
Yet another flavor of solution that uses sorted:
def find_integer_with_most_divisors(input_list):
def divisor_length(num):
length = 0
for i in range(1,num+1):
if num % i == 0:
length += 1
return length
return sorted(input_list, key=lambda x: divisor_length(x), reverse=True)[0]
print(find_integer_with_most_divisors([8,12,18,6]))
12

Treating index of a list as a integer

I'm doing some sample programming challenges to practice for a upcoming competition, and I've found myself stumped on a rather easy challenge.
Basically, the user has to enter x amount of numbers, and I have to return the sum of the numbers. The condition is that every time they enter 0, it means i have to disregard the last number that they entered, so it will not be apart of the sum anymore.
Here is my code:
numbers = []
index = 0
total = 0
k = input("How many numbers would you like to enter? (1- 100000)" + "\n").strip()
for x in range (int(k)):
number = input("Enter a number." + "\n").strip()
numbers.append(number)
if number == '0':
index = numbers.index(number)
numbers.pop([index - 1])
numbers.pop([index])
for y in range (len(numbers)):
for item in numbers:
total += int(item)
print(total)
error on this line:
numbers.pop([index - 1])
It tells me that 'list' object cannot be interpreted as an integer. I originally tried to make it int(index) hoping that it would convert it into an int so i can carry out the subtraction to get the index of the number before it so i can pop it out of the list, but I got the same error message.
Is there any way to use this value as an integer so I can carry out the subtract one. Or is there a different way required to get the index of the number before?
well, in python, one can refer to elements at the end of the list with negative numbers:
>>> l = range(10, 100, 5)
>>> l
[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
>>> l[-1]
95
>>> l[-2]
90
and pop will take these negative numbers, so to delete the second to last item in the list is just:
>>> l.pop(-2)
90
>>> l
[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 95]
What do you think [index - 1] is? It's obviously a list. And that's not an integer. index - 1, without the square brackets, would be an integer. Also, you should check for whether the user's number is 0 before appending it, or the last value in the list will be that 0 rather than the value you need to remove, which just makes for extra work.
There's also a lot of room for improvement in your code, along the lines of making proper use of built-ins and eliminating unnecessary counters:
k = int(input("How many numbers would you like to enter? (1- 100000)\n"))
result = []
for i in range(k):
num = int(input("Enter a number.\n"))
if num:
result.append(num)
elif result:
result.pop(-1)
print(sum(result))
It should be numbers.pop(index - 1)
What you have to do is to pass the integer value of the index that needs to be popped, rather than passing a list.
Try this
numbers = []
index = 0
total = 0
k = input("How many numbers would you like to enter? (1- 100000)" + "\n").strip()
for x in range (int(k)):
number = input("Enter a number." + "\n").strip()
numbers.append(number)
if number == '0':
index = numbers.index(number)
numbers.pop(index - 1)
numbers.pop(index)
for y in range (len(numbers)):
for item in numbers:
total += int(item)
print(total)
You are passing a list, when you should pass an int
numbers.pop(index-1)
code:
numbers = []
index = 0
total = 0
k = input("How many numbers would you like to enter? (1- 100000)" + "\n").strip()
for x in range (int(k)):
number = input("Enter a number." + "\n").strip()
numbers.append(number)
if number == '0':
index = numbers.index(number)
numbers.pop(index)
numbers.pop(index-1)
for y in range (len(numbers)):
for item in numbers:
total += int(item)
print(total)
And if I may, this is an easier way of doing it
total = 0
last = 0
k = input("How many numbers would you like to enter? (1- 100000)" + "\n").strip()
for x in range (int(k)):
print("Enter Number")
temp = int(input())
total += temp
if temp == 0:
total -= last
else:
last = temp
print(total)

Categories

Resources