Related
I have following variables;
D8 =[22, 27, 28, 30, 31, 40, 41, 42, 43, 45]
D9 = [79, 80, 90, 92, 93, 97, 98, 104, 105, 109]
D10=[61, 64, 66, 70, 72, 76, 81, 86, 87]
By using above variables, I tried to generate all the possible combinations as follows;
import itertools
stuff = [D8, D9, D10]
for L in range(0, len(stuff)+1):
for subset in itertools.combinations(stuff, L):
print(subset)
The result depicts as follows;
Output>>>
()
([22, 27, 28, 30, 31, 40, 41, 42, 43, 45],)
([79, 80, 90, 92, 93, 97, 98, 104, 105, 109],)
([61, 64, 66, 70, 72, 76, 81, 86, 87],)
([22, 27, 28, 30, 31, 40, 41, 42, 43, 45], [79, 80, 90, 92, 93, 97, 98, 104, 105, 109])
([22, 27, 28, 30, 31, 40, 41, 42, 43, 45], [61, 64, 66, 70, 72, 76, 81, 86, 87])
([79, 80, 90, 92, 93, 97, 98, 104, 105, 109], [61, 64, 66, 70, 72, 76, 81, 86, 87])
([22, 27, 28, 30, 31, 40, 41, 42, 43, 45], [79, 80, 90, 92, 93, 97, 98, 104, 105, 109], [61, 64, 66, 70, 72, 76, 81, 86, 87])
I want to know is there any other cleaner method to generate the above result, because in the current output I cannot flat each result into each individual outcome? Expected result should be like this?
Expected Result>>>
([])
([22, 27, 28, 30, 31, 40, 41, 42, 43, 45])
([79, 80, 90, 92, 93, 97, 98, 104, 105, 109])
([61, 64, 66, 70, 72, 76, 81, 86, 87])
([22, 27, 28, 30, 31, 40, 41, 42, 43, 45, 79, 80, 90, 92, 93, 97, 98, 104, 105, 109])
([22, 27, 28, 30, 31, 40, 41, 42, 43, 45, 61, 64, 66, 70, 72, 76, 81, 86, 87])
([79, 80, 90, 92, 93, 97, 98, 104, 105, 109, 61, 64, 66, 70, 72, 76, 81, 86, 87])
([22, 27, 28, 30, 31, 40, 41, 42, 43, 45, 79, 80, 90, 92, 93, 97, 98, 104, 105, 109, 61, 64, 66, 70, 72, 76, 81, 86, 87])
Thank you in advanced!!!
The itertools documentation contains the recipe flatten:
def flatten(list_of_lists):
"Flatten one level of nesting"
return chain.from_iterable(list_of_lists)
which you need to apply twice to get the desired result:
from itertools import combinations, chain
D8 = [22, 27, 28, 30, 31, 40, 41, 42, 43, 45]
D9 = [79, 80, 90, 92, 93, 97, 98, 104, 105, 109]
D10 = [61, 64, 66, 70, 72, 76, 81, 86, 87]
stuff = [D8, D9, D10]
def flatten(list_of_lists):
"""Flatten one level of nesting"""
return chain.from_iterable(list_of_lists)
result = flatten(map(flatten, combinations(stuff, length)) for length in range(len(stuff) + 1))
for xs in result:
print(list(xs))
producing:
[]
[22, 27, 28, 30, 31, 40, 41, 42, 43, 45]
[79, 80, 90, 92, 93, 97, 98, 104, 105, 109]
[61, 64, 66, 70, 72, 76, 81, 86, 87]
[22, 27, 28, 30, 31, 40, 41, 42, 43, 45, 79, 80, 90, 92, 93, 97, 98, 104, 105, 109]
[22, 27, 28, 30, 31, 40, 41, 42, 43, 45, 61, 64, 66, 70, 72, 76, 81, 86, 87]
[79, 80, 90, 92, 93, 97, 98, 104, 105, 109, 61, 64, 66, 70, 72, 76, 81, 86, 87]
[22, 27, 28, 30, 31, 40, 41, 42, 43, 45, 79, 80, 90, 92, 93, 97, 98, 104, 105, 109, 61, 64, 66, 70, 72, 76, 81, 86, 87]
The following code partitions a list in spaces of 5.
o_list = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
def partition(lst, size):
for i in range(0, len(lst), size):
yield lst[i :: size]
# size of each partition
n = 5
p_list = list(partition(o_list, n))
print("Original List: ")
print(o_list)
print("Partitioned List:")
print(p_list)
The following are the results:
Original List:
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
Partitioned List:
[[10, 60, 110, 160], [60, 110, 160], [110, 160], [160]]
However I want the second array to be [20, 70, 120, 170] and the third and so on follow suit.
Just replace the comma in the range function to a // operator:
o_list = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
def partition(lst, size):
for i in range(0, len(lst) // size):
yield lst[i :: size]
# size of each partition
n = 5
p_list = list(partition(o_list, n))
print("Original List: ")
print(o_list)
print("Partitioned List:")
print(p_list)
This prints:
Original List:
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
Partitioned List:
[[10, 60, 110, 160], [20, 70, 120, 170], [30, 80, 130, 180], [40, 90, 140, 190]]
Something like this?
o_list = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
[o_list[x::5] for x in range(len(o_list)//5)]
[[10, 60, 110, 160],
[20, 70, 120, 170],
[30, 80, 130, 180],
[40, 90, 140, 190]]
With division you can figure out how many slices can be produced, then simply produce those slices in a loop.
partition = lambda L, N: [L[n::N] for n in range(len(L)//N)]
print(partition(list(range(10, 201, 10)), 5))
#[[10, 60, 110, 160], [20, 70, 120, 170], [30, 80, 130, 180], [40, 90, 140, 190]]
This is what I have so far, but I would like to use it without min and with for loop:
Numbers = [100, 97, 72, 83, 84, 78, 89, 84, 83, 75, 54, 98, 70, 88, 99, 69, 70, 79, 55, 82, 81, 75, 54, 82, 56, 73, 90, 100, 94, 89, 56, 64, 51, 72, 64, 94, 63, 82, 77, 68, 60, 93, 95, 60, 77, 78, 74, 67, 72, 99, 93, 79, 76, 86, 87, 74, 82]
for i in range(len(Numbers)):
print(min(Numbers))
I do not know why you do not want to use min (you should) - but if you do not want to you can loop over the numbers and keep track of the smallest.
min_ = None
for n in Numbers:
if min_ is None or n < min_:
min_ = n
min_ is now the minimum in the list Numbers.
Another identical method is:
numbers = [100, 97, 72, 83, 84, 78, 89, 84, 83, 75, 54, 98, 70, 88, 99, 69, 70, 79, 55, 82, 81, 75, 54, 82, 56, 73, 90, 100, 94, 89, 56, 64, 51, 72, 64, 94, 63, 82, 77, 68, 60, 93, 95, 60, 77, 78, 74, 67, 72, 99, 93, 79, 76, 86, 87, 74, 82]
smallest = None
for x in range(len(numbers)):
if (smallest == None or numbers[x] < smallest):
smallest = numbers[x]
print(smallest)
Output:
51
I am writing a grade book program that sets a nested list with assignments as columns and individual students along the rows. The program must calculate the average for each assignment and the average for each student. I've got the average by student, but now I can't figure out how to calculate the average by assignment. Any help would be appreciated!
# gradebook.py
# Display the average of each student's grade.
# Display tthe average for each assignment.
gradebook = [61, 74, 69, 62, 72, 66, 73, 65, 60, 63, 69, 63,
62, 61, 64],
[73, 80, 78, 76, 76, 79, 75, 73, 76, 74, 77, 79, 76,
78, 72],
[90, 92, 93, 92, 88, 93, 90, 95, 100, 99, 100, 91, 95, 99, 96],
[96, 89, 94, 88, 100, 96, 93, 92, 94, 98, 90, 90, 92, 91, 94],
[76, 76, 82, 78, 82, 76, 84, 82, 80, 82, 76, 86, 82, 84, 78],
[93, 92, 89, 84, 91, 86, 84, 90, 95, 86, 88, 95, 88, 84, 89],
[63, 66, 55, 67, 66, 68, 66, 56, 55, 62, 59, 67, 60, 70, 67],
[86, 92, 93, 88, 90, 90, 91, 94, 90, 86, 93, 89, 94, 94, 92],
[89, 80, 81, 89, 86, 86, 85, 80, 79, 90, 83, 85, 90, 79, 80],
[99, 73, 86, 77, 87, 99, 71, 96, 81, 83, 71, 75, 91, 74, 72]]
#make variable for assingment averages
#make a variable for student averages
stu_avg = [sum(row)/len(row) for row in gradebook]
print(stu_avg)
#Assignment Class
class Assignment:
def __init__(self, name, average):
self.average = average
self.name = name
def print_grade(self):
print("Assignment", self.name, ":", self.average)
#Student Class
class Student:
def __init__(self, name, average):
self.average = average
self.name = name
def print_grade(self):
print("Student", self.name, ":", self.average)
s1 = Student("1", stu_avg[0])
s2 = Student("2", stu_avg[1])
s3 = Student("3", stu_avg[2])
s4 = Student("4", stu_avg[3])
s5 = Student("5", stu_avg[4])
s6 = Student("6", stu_avg[5])
s7 = Student("7", stu_avg[6])
s8 = Student("8", stu_avg[7])
s9 = Student("9", stu_avg[8])
s10 = Student("10", stu_avg[9])
s1.print_grade()
s2.print_grade()
s3.print_grade()
s4.print_grade()
s5.print_grade()
s6.print_grade()
s7.print_grade()
s8.print_grade()
s9.print_grade()
s10.print_grade()
Instead of using loops, let's use matrices. They make calculation much much faster, especially when dealing with large datasets.
As an example,
Per student:
[1, 2, 3, 4] [1]
[4, 5, 6, 6] x [1]
[1, 1, 3, 1] [1]
Per assignment
[1, 2, 3, 4]T [1]
[4, 5, 6, 6] x [1]
[1, 1, 3, 1] [1]
The first operation returns per student sum, and the second returns per test sum. Divide appropriately to get the average.
Using numpy
import numpy as np
gradebook = [[61, 74, 69, 62, 72, 66, 73, 65, 60, 63, 69, 63, 62, 61, 64],
[73, 80, 78, 76, 76, 79, 75, 73, 76, 74, 77, 79, 76, 78, 72],
[90, 92, 93, 92, 88, 93, 90, 95, 100, 99, 100, 91, 95, 99, 96],
[96, 89, 94, 88, 100, 96, 93, 92, 94, 98, 90, 90, 92, 91, 94],
[76, 76, 82, 78, 82, 76, 84, 82, 80, 82, 76, 86, 82, 84, 78],
[93, 92, 89, 84, 91, 86, 84, 90, 95, 86, 88, 95, 88, 84, 89],
[63, 66, 55, 67, 66, 68, 66, 56, 55, 62, 59, 67, 60, 70, 67],
[86, 92, 93, 88, 90, 90, 91, 94, 90, 86, 93, 89, 94, 94, 92],
[89, 80, 81, 89, 86, 86, 85, 80, 79, 90, 83, 85, 90, 79, 80],
[99, 73, 86, 77, 87, 99, 71, 96, 81, 83, 71, 75, 91, 74, 72]]
def get_student_average(gradebook):
number_of_students = len(gradebook[0])
number_of_assignments = len(gradebook)
matrix = [1] * number_of_students
# [1, 1, 1, 1, ...]. This is 1 * 15. Need to transpose to make it 15*1
# Converting both to numpy matrices
matrix = np.array(matrix)
gradebook = np.array(gradebook)
# Transposing matrix and multiplying them
print(gradebook.dot(matrix.T))
def get_assignment_average(gradebook):
number_of_students = len(gradebook[0])
number_of_assignments = len(gradebook)
matrix = [1] * number_of_assignments
# [1, 1, 1, ...] . This is 1 * 10. Need to transpose to make it 10*1
matrix = np.array(matrix)
gradebook = np.array(gradebook)
gradebook = gradebook.T
matrix = matrix.T
print(gradebook.dot(matrix))
get_student_average(gradebook)
get_assignment_average(gradebook)
Results
student_avg -> [ 984 1142 1413 1397 1204 1334 947 1362 1262 1235]
test_avg -> [826 814 820 801 838 839 812 823 810 823 806 820 830 814 804]
I'm working with pyplot.subplot() to make a bar chart and then save as an image. Currently the savefig is saving an empty image. I guess I'm a little stuck since there's not many examples I have found for bar and subplot.
Here's the code:
nums = [57, 83, 66, 90, 84, 83, 83, 64, 58, 94, 94, 79, 95, 61, 67, 79, 70, 86, 84, 57, 80, 98, 54, 82, 74, 87, 69, 55, 59, 87, 76, 53, 80, 89, 66, 68, 95, 89, 65, 69, 81, 55, 53, 77, 54, 88, 90, 73, 77, 63, 75, 98, 78, 62, 61, 91, 90, 69, 93, 80, 69, 63, 71, 57, 77, 76, 77, 67, 91, 66, 51, 98, 66, 96, 62, 98, 78, 86, 60, 93, 60, 62, 72, 71, 55, 55, 82, 99, 83, 61, 69, 58, 68, 71, 67, 87, 64, 50, 60]
gradeA = []
gradeB = []
gradeC = []
gradeD = []
gradeF = []
for a in nums:
if a in range(90,100):
gradeA.append(a)
if a in range(80,89):
gradeB.append(a)
if a in range(70,79):
gradeC.append(a)
if a in range(60,69):
gradeD.append(a)
if a in range(0,59):
gradeF.append(a)
import numpy as np
import matplotlib.pyplot as plt
gradeCounts = (len(gradeF), len(gradeD), len(gradeC), len(gradeB), len(gradeA))
# the x locations for the bars
ind = np.arange(5)
#bar width
width = 0.35
#draw graph
ax = plt.subplot()
#set up colors for different bars
colors = ['r','orange','y','g','b']
ax.bar(ind+.5*width, gradeCounts, width, color=colors)
# add some text for labels, title and axes ticks
ax.set_title('Grade Range')
ax.set_xticks(ind+width)
ax.set_xticklabels( ('F', 'D', 'C', 'B', 'A') )
plt.show()
plt.savefig('test.png')
Get rid of the penultimate line, plt.show()
Here is the result of running your code without that line