Lists, Loops, Average Python - python

I'm currently having an issue with my code. The program works properly but for some reason when I enter all positive numbers I receive an error for the last function. The last function is removing all the negative numbers from the list.
i=0
numList = []
x = int(input("Please enter number from -9999 to end:"))
while x > -9999:
i = i + 1
numList.insert(i,x)
x = int(input("Please enter number from -9999 to end:"))
if x == -9999:
print("The list of numbers entered:",(numList))
newList = numList[:]
secList = numList[:]
def posNumAvg(newList):
for e in newList[:]:
if e < 0:
newList.remove(e)
def negNumAvg(secList):
for y in secList[:]:
if y > 0:
secList.remove(y)
posNumAvg(newList)
negNumAvg(secList)
mydict = {'AvgPositive':(sum(newList)//len(newList)),'AvgNonPos': (sum(secList)//len(secList)),'AvgAllNum':(sum(numList)//len(numList))}
print("The dictionary with averages is:",mydict)

You are trying to compute the average of an empty list, which is not defined (specifically, the list's length is zero so you end up dividing by zero).
You need to decide what you want to do in that case and handle it specifically.
As an aside, you can rewrite
for e in newList[:]:
if e < 0:
newList.remove(e)
as
newList = [e for e in newList if e >= 0]

NOte: Never modify the list when you iterating over it. Let me make some changes to your code
numList = []
while True:
x = int(input("Please enter number from -9999 to end:")
if x == -9999:
print("The list of numbers entered:",(numList))
break
# you don't need i here, used append to insert element at last of list
# insert is used to insert a element at specific position
numList.append(x)
def posNumAvg(gotList):
list_negative = [] # will contain negative number
for e in gotList:
if e < 0:
list_negative.append(e)
return list_negative
def negNumAvg(gotList):
list_positive = [] # will contain positive number
for y in gotList:
if y >= 0:
list_positive.append(y)
return list_positive
list_positive = posNumAvg(numList)
list_negative = negNumAvg(numList)
mydict = {'AvgPositive':(sum(list_positive)//len(list_positive)),'AvgNonPos': (sum(list_negative)//len(list_negative)),'AvgAllNum':(sum(numList)//len(numList))}
print("The dictionary with averages is:",mydict)
you can get positive and negative number from one function: see this code
def neg_poss(gotList):
list_positive = [] # will contain positive number
list_negative = [] # will contain negative number
for y in gotList:
if y >= 0:
list_positive.append(y)
else:list_negative.append(y)
return list_positive,list_negative
list_positive,list_negative = neg_post(numList)

Related

How to find the second lowest and second highest element in a list?

So, the function works with no errors, but the output for min2(2nd lowest value) in the list is incorrect. I cant seem to find the solution.
Python 3.8.6
def max2min2(list1):
max1=list1[0]
min1=list1[0]
max2=None
min2=None
for item in list1:
if item>max1:
max2=max1
max1=item
elif max2==None or max2<item:
max2=item
if item<min1:
min2=min1
min1=item
elif min2==None or min2>item:
min2=item
return max2,min2
list1 = [1,2,3]
max2,min2=max2min2(list1)
print(min2,max2) # 1 2
With the simple input list of [1,2,3] the output of maxmin2 is (1,2), although the expected output is (2,2).
Now if this does not to need to be speed optimized, simple way would be just take a set of the numbers, sort them, and take the second element from each end:
vals = [1,1,3,2,2]
filtered_vals = sorted(set(vals))
and then
# Second lowest
In [37]: filtered_vals[1]
Out[37]: 2
# Second highest
In [36]: filtered_vals[-2]
Out[36]: 2
add some Exception and special case handling if needed.
A simple and readable solution is to sort the list first, then directly index the values you want. I added a unique argument which specifies whether you want to look at the number values (most intuitive) or keep duplicate values in the list (so that the second highest number in [1,2,2] is 2).
def second_lowest_and_highest_using_sort(nums, unique=True):
if unique:
nums = list(set(nums))
if len(nums) == 1:
raise ValueError('Second lowest/highest number is undefined for a list of length 1.')
nums = sorted(nums)
return (nums[1], nums[-2])
A more verbose approach without sorting first:
def second_lowest_and_highest(nums, unique=True):
if unique:
nums = list(set(nums))
if len(nums) == 1:
raise ValueError('Second lowest/highest number is undefined for a list of length 1.')
lowest, highest = float('inf'), float('-inf')
second_lowest, second_highest = None, None
low_delta, high_delta = float('inf'), float('inf')
for num in nums:
low_delta_new = num - lowest
if low_delta_new < 0:
second_lowest = lowest
lowest = num
elif low_delta_new <= low_delta:
second_lowest = num
low_delta = low_delta_new
high_delta_new = num - highest
if high_delta_new > 0:
second_highest = highest
highest = num
elif high_delta_new <= high_delta:
second_highest = num
high_delta = high_delta_new
return (second_lowest, second_highest)

How can I change the value of "items" with this function? It would be an example of validation using recursion

If the input stored in items is correct, then items remains the original value. But if the input is incorrect, it prompts the user to input new items and stores that value in the original items variable. My problem is that my code does not store the new input in the global items variable. I have tried using the global keyword to no avail. I cannot use for/while loops and only standard libraries.
Here is my code:
items = input("Please enter integers").split()
items = list(map(int, items))
def checksYn(p):
if max(p) > 100 or min(p) < -100:
new_items = input("Please enter integers between -100 and 100").split()
new_items = list(map(int, new_items))
checksYn(new_items)
global items
items = p
print(items)
The following code will solve your problem:
items = input("Please enter integers").split()
items = list(map(int, items))
def checksYn(p):
if max(p) > 100 or min(p) < -100:
new_items = input("Please enter integers between -100 and 100").split()
new_items = list(map(int, new_items))
return checksYn(new_items)
else:
return p
x=checksYn(items)
print(x)
Let's design a program which works like this -
Please enter integers:
1 2 300
Please enter integers between -100 and 100:
1 two 3
Please enter integers between -100 and 100:
-5 1 2 three
Please enter integers between -100 and 100:
-99 1 2 3
done: [-99, 1, 2, 3]
We start a rough sketch of a recursive program, main -
def main(nums):
try:
return validate(nums)
except:
return main(retry())
nums = main(init())
print(f"done: {nums}")
Now we just implement init and retry -
def init():
return get_user_input("Please enter integers")
def retry():
return get_user_input("Please enter integers between -100 and 100")
def get_user_input(prompt):
return input(f"{prompt}:\n").split()
And finally write validate -
def validate(nums):
r = []
for x in map(int, nums):
if x < -100 or x > 100:
raise ValueError
else:
r.append(x)
return r
You're all done!

List not concatenating properly in python

My code all work fine apart from the list at the very bottom "newList = [i + j for i, j in zip(numberString, products)]". I expected it to add all the elements within the two list without fault, sort of like this: [a9, b7, c5, d3, e1].
Instead i got this: "['[a', '[b', '9c', ',d', ' e']". Both lists are strings, so i'm not sure why they aren't concatenating properly.
# create an empty list for your products.
products = []
# Asking for the number of elements to be inputted.
n = int(input("Enter number of products you're buying : "))
# Some UI for the customer.
print("What are these products?")
# iterating until the range that has been chosen.
for i in range(0, n):
ele = input()
products.append(ele) # adding the element
def sort_numbers(number_list):
# sorts a list of valid numbers in descending numerical order
swaps = True
loopcount = len(number_list) - 1
while loopcount > 0 and swaps:
swaps = False
for i in range(loopcount):
if number_list[i] < number_list[i + 1]:
number_list[i], number_list[i + 1] = number_list[i + 1], number_list[i]
swaps = True
loopcount = loopcount - 1
def input_numbers(number_list):
# inputs shopping items and costs and stores them in two lists
user_input = input('Input a number of type Q to quit ')
while user_input.upper() != 'Q':
valid_number = False
while valid_number == False:
# use an exception handler to cover non-numeric input
try:
number_list.append(int(user_input))
valid_number = True
except ValueError:
print('Please enter a valid number')
user_input = input('Input a number or type Q to quit ')
user_input = input('input a number or type Q to quit ')
def totalise_numbers(number_list):
# sums us the list of numbers
total = 0
for i in range(len(number_list)):
total = total + number_list[i]
print('The total of the numbers is ', total)
print('The total of the numbers minus the smallest number is ', total - number_list[0])
# initialise the list
numbers = []
# call the function to create the list of numbers
input_numbers(numbers)
# sort the list in ascending order
sort_numbers(numbers)
# Totalise the numbers
totalise_numbers(numbers)
numberString = str([numbers])
# print the list of numbers
newList = [i + j for i, j in zip(numberString, products)]
print(newList)
print(numbers)
Replace the few bottom lines with this code.
numberString = numbers
# print the list of numbers
newList = [str(i) + j for i, j in zip(numberString, products)]
print(newList)
print(numbers)

Python if problem with analyzing numbers if number before is positive or negative?

so my goal is to make program that scans numbers and if number before zero is negative and number after zero is positive it prints "Zero is positive" and if opposite "Zero is negative". Problem is that every time i enter numbers it always prints only "Zero is negative" for now program should only work with 1 zero and 2 numbers but i will later expend. Here is my code:
number = input("Enter Numbers: ")
lists = []
lists = number.split()
print(lists)
z = 0
y = 0
x = 0
indexes = [index for index, element in enumerate(lists) if element == "0"]
print(indexes)
pos = indexes[0] - 1
neg = indexes[0] + 1
zero = indexes[0]
if(int(neg) < zero and zero > int(pos)):
print("Zero is postive")
else:
print("Zero is negative")
As already been told, you should compare the values in the list not the index numbers.
Also, there is a logical error in this statement if(int(neg) < zero and zero > int(pos)):, it actually checks if both neg and both are less that zero.
And perhaps is more clear if neg points the previous to zero value and pos the next one.
I modified a bit your code and I think it works correctly:
number = input("Enter Numbers: ")
lists = []
lists = number.split()
print(lists)
z = 0
y = 0
x = 0
indexes = [index for index, element in enumerate(lists) if element == "0"]
print(indexes)
neg = int(indexes[0] - 1)
pos = int(indexes[0] + 1)
zero = int(indexes[0])
if lists[neg] < lists[zero] < lists[pos]:
print("Zero is postive")
else:
print("Zero is negative")
If I'm understanding the problem statement correctly, you need to compare the list elements at the indexes but are comparing the indexes. So the condition in if should be changed from:
if(int(neg) < zero and zero > int(pos)):
to something like this (note that you don't need braces in python's if):
if list[neg] > list[zero] > list[pos]:

Python Lists - Highest & Lowest

i am creating a python program, to allow a user to input numbers and find the total, average, highest and lowest of the numbers inputted. my teacher has told me to improve the program by removing the first and last number(which i have now done ) inputted into the list and not to use the min and max functions.I am confused on how doing so.
totalList=[]
TotalNum = int(input("Please enter how many numbers are to be entered:"))
Change=TotalNum
Input=0
Total=0
while TotalNum>0:
TotalNum = TotalNum - 1
Input = int(input("Enter Number: "))
totalList.append(Input)
Total = Total +Input
while 1 == 1:
totalList = totalList[1:-1]
TotalList = totalList
print("Total:" ,Total)
print("Average:",Total/Change)
print("Highest:",max(TotalList))
print("Lowest:",min(TotalList))
When removing the first and last numbers of the list, since lists are zero-indexed in python (meaning the first number is at index 0), you'll want to change totalList = totalList[1:-1] to start from 0, making it totalList = totalList[0:-1].
However, we may want to use those first and last numbers when searching for the maximum and minimum numbers in the list. So, I think what your teacher may have meant was to use the first and last numbers as min and max, and update them as you search through the list.
I will show you finding the minimum, and then using the same idea you can find the maximum.
min_num = TotalList[0]
max_num = TotalList[-1]
for i in TotalList:
if i < min_num:
i = min_num
# print("Highest:",max_num)
print("Lowest:", min_num)
Note: You don't need the infinite while 1 == 1: loop, delete it.
def find_low(nums, index):
lowest = None
lowNum = float("inf")
for num in nums:
if num < lowNum:
lowNum = num
lowest = num
highest = None
highNum = -float("inf")
for num in nums:
if num > highNum:
highNum = num
highest = num
Used = []
newL = []
for num in range(lowest, highest + 1):
if num in nums and not num in Used:
newL.append(num)
Used.append(num)
return newL[index - 1]
numbers = [1,2,3,4,5]
print(find_low(numbers, 1))
#The second paramter, 1, finds the lowest number, not 0

Categories

Resources