Can't get a descending sorted list. Its sorting for positive number but not for negative numbers. Why? Please see output below. Python version 3.9.7 - python-3.x

This question is for my assignment so I can't use built-in function for max and sorting
myMax() returns the maximum number from a list and mySort() sorts in descending order
Input I am giving
Please enter a list of different numbers separated by ',' : 1,-3,4.5,5,18,-1,3,-4
def myMax(a_list):
max_num=a_list[0]
print(a_list)
location=0
counter=1
list_size=len(a_list)
while(counter<list_size):
if(max_num<a_list[counter]):
max_num=a_list[counter]
location=counter+1
counter+=1
return max_num,location
def mySort(a_list):
list_size=len(a_list)
counter=0
des_list=[]
while(counter<list_size):
max_num,location=myMax(a_list)
des_list.append(max_num)
a_list.pop(location-1)
counter+=1
return des_list
input_list= input("Please enter a list of different numbers separated by ',' : ")
input_list=input_list.split(",")
input_list=[int(i) for i in input_list]
print("The descending sorted list is {}.".format(mySort(input_list)))
Input:
1,-3,4.5,5,18,-1,3,-4
Output I am getting:
The descending sorted list is [18, 5, 4.5, 3, 1, 1, 1, 1]
Output I am expecting:
The descending sorted list is [18, 5, 4.5, 3, 1,-1,-3,-4]

Related

How to sort a dictionary of nested lists by value with one key ascending and one key descending?

I'm working on a problem that states the following:
Write a function telling apart accepted and refused students according to a threshold.
The function should be called select_student and takes as arguments:
A list where each element is a list of a student name, and his mark.
A mark. The student mark must be superior or equal to the given mark to be accepted.
Your function must return a dictionary with two entries:
Accepted which list the accepted students sorted by marks in the descending order.
Refused which list the refused students sorted by marks in ascending order.
Example
In [1]: from solution import select_student
In [2]: my_class = [['Kermit Wade', 27], ['Hattie Schleusner', 67], ['Ben Ball', 5], ['William Lee', 2]]
In [3]: select_student(my_class, 20)
Out[3]:
{'Accepted': [['Hattie Schleusner', 67], ['Kermit Wade', 27]],
'Refused': [['William Lee', 2], ['Ben Ball', 5]]}
In [4]: select_student(my_class, 50)
Out[4]:
{'Accepted': [['Hattie Schleusner', 67]],
'Refused': [['William Lee', 2], ['Ben Ball', 5], ['Kermit Wade', 27]]}
My code is:
from collections import OrderedDict
students = [
["Kermit Wade", 27],
["Hattie Schleusner", 67],
["Ben Ball", 5],
["William Lee", 2],
]
def select_student(students, threshold):
output = {
'Accepted' : [],
'Refused' : []
}
for i in range(len(students)):
if students[i][1] >= threshold:
output['Accepted'].append(students[i])
elif students[i][1] < threshold:
output['Refused'].append(students[i])
return output
My output is:
{'Accepted': [['Kermit Wade', 27], ['Hattie Schleusner', 67]], 'Refused': [['Ben Ball', 5], ['William Lee', 2]]}
The output is for these parameters
print(select_student(students, 20))
As you can see I need to reverse the order for both accepted and refused. So Hattie comes first in accepted and then William comes first in refused.
I tried to use OrderedLists and googling but because of the nested list structure required by the problem I could not find a way to sort by the grade nor could I find a way to have it both be ascending and descending depending on the dictionary's key.
Thanks in advance!
Modify your select student function to sort your accepted and refused lists as follows:
def select_student(students, threshold):
output = {
'Accepted' : [],
'Refused' : []
}
for i in range(len(students)):
if students[i][1] >= threshold:
output['Accepted'].append(students[i])
elif students[i][1] < threshold:
output['Refused'].append(students[i])
output['Accepted'] = sorted(output['Accepted'], key= lambda x: x[1], reverse= True)
output['Refused'] = sorted(output['Refused'], key = lambda x: x[1])
return output

How can I count the number of times a specific number appears in list vertically in python 3?

I'm trying to count the number of times a specific number appears in serval lists vertically.
My code:
import csv
with open('Superheroes.csv', 'r') as csvfile:
first_line = csvfile.readline()
super_reader = csv.reader(csvfile, delimiter=',')
result = []
for vote in super_reader:
vote.pop(0)
result.append([int(x) if x else 0 for x in vote])
result = [vote.count(1) for i in zip(*result)]
print(result)
example picture
So from the example picture, say I wanted to know how many times the number 11 appeared in every column of all the lists. I would expect an output of [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 4, 2]
Thanks
You can use sum with a generator expression that outputs whether each item in a column matches the target number to perform the counting after transposing the rows into columns with zip:
def count(rows, num):
return [sum(i == num for i in map(int, col)) for col in zip(*rows)]
so that given the content of test.csv as follows:
2,1,3
3,2,1
1,3,3
1,3,2
count(csv.reader(open('test.csv')), 3) would return:
[1, 2, 2]
Demo: https://repl.it/#blhsing/IllAffectionateQuarks#main.py

Can't seem to get this for loop to work with range

numbers = [5, 9, 13, 17, 21]
for list in range(5,22,4):
print(numbers[list], end =" ")
Can't seem to get it to work, keep getting
IndexError: list index out of range
Your numbers variable has an index from 0-4 (python starts at 0 and increments from there) - your range command is giving you the numbers:
[5, 9, 13, 17, 21]
You're telling python that you want to go from the number 5 to the number 22, in steps of 4. This means that when you try and print numbers[list], the variable list is actually the index 5 on the iteration of the for loop, and will be outside of the index range of the numbers variable, since it only has indices 0, 1, 2, 3, and 4
Your code seems to confuse two approaches to solving the same task.
One is printing the existing list of numbers:
numbers = [5, 9, 13, 17, 21]
for number in numbers:
print(number, end=" ")
# or, alternatively
for index in range(len(numbers)):
print(numbers[index], end=" ")
Another is generating the same sequence of numbers using range() function:
for number in range(5,22,4):
print(number, end=" ")
# or, reusing one of the previous approaches
numbers = range(5,22,4)
for number in numbers:
print(number, end=" ")
Bear in mind that range() creates a range object, which is suitable for enumeration and indexing, but does not support other list operations like slicing, concatenation and repeating (concatenation with itself). If you want to get numbers as a list, write explicitly:
numbers = list(range(5,22,4))
and then you can do:
for number in numbers * 2:
print(number, end=" ")
which will print your sequence of numbers twice.

how to calculate the sum of elements other than the specified indices?

I have a 3*3 array of values
array([[20, 10, 30],
[35, 45, 25],
[15, 25, 35]])
I want to create a function where, when I pass a number argument it should sum all the rows and column elements smaller than the elements which fall on the number.
def sum_con (ar,a):
y=a-1
z=ar[0][0]+ar[0][1]+ar[1][0]+ar[1][1]
return z
sum_con(array,2)
>>110
But you can see this code is not dynamic as it is not scaleable.
Can someone provide code for doing the same functionality for n shaped array.?
For "other than", simply do the sum as usual and subtract/add accordingly:
def sum_con(a, n):
return a.sum() - a[n].sum() - a[:,n].sum() + a[n,n]
This will make the n'th row and column "disappear" when summing.
For "smaller than", it's even easier:
def sum_con_2(a, n):
return a[:n,:n].sum()

Get a list of all number in a certain range containing only certain digits without checking each number

Is there a way to create a list of all numbers less than 10,000 that do not contain any of the digits 0, 2, 4, 5, 6, 8? Of course one can simply type something like:
bads = ['0', '2', '4', '5', '6', '8']
goods = []
for n in range(1, 10000, 2):
if not any(bad in str(n) for bad in bads):
goods.append(n)
However, I'm looking for a method which instead considers the digits 1, 3, 7, 9 and creates all possible unique strings of permutations of these numbers of size 4 or less, duplicate digits allowed. Does itertools, for example, have something that would easily do this? I looked at the permutations method, but that doesn't produce numbers with repeated digits from the collection, and the product method doesn't seem to be what I'm after either, given that it simply would return Cartesian products of 1, 3, 5, 7 with itself.
Here's a simple-minded approach using permutations and combinations_with_replacement from itertools:
from itertools import permutations, combinations_with_replacement
def digit_combinations(power_of_ten):
numbers = set()
for n in range(1, power_of_ten + 1):
for combination in combinations_with_replacement("1379", n):
numbers |= set(permutations(combination, len(combination)))
return sorted(int(''.join(number)) for number in numbers)
print(digit_combinations(4))
OUTPUT
[1, 3, 7, 9, 11, 13, 17, 19, ..., 9971, 9973, 9977, 9979, 9991, 9993, 9997, 9999]
It could be made more space efficient using generators, but depending on the range, it might not be worth it. (For up to 10,000 there are only 340 numbers.) For numbers to 10^4, this code takes roughly as long as your simple example. But for 10^7, this code runs over 40x faster on my system than your simple example.
Could you include your idea for the generator?
Here's a basic rework of the code above into generator form:
from itertools import permutations, combinations_with_replacement
def digit_combinations_generator(power_of_ten):
for n in range(1, power_of_ten + 1):
for combination in combinations_with_replacement("1379", n):
for number in set(permutations(combination, len(combination))):
yield int(''.join(number))
generator = digit_combinations_generator(4)
while True:
try:
print(next(generator), end=', ')
except StopIteration:
print()
break
This does not return the numbers sorted, it just hands them out as fast as it generates them.

Resources