Which data structure to store inputted numbers? - python

Which data structure is best for calculating average of inputted numbers ?
I used an array, but it feels clumsy.
Is there a more standard way to do this?
import os
def getGrades():
g = input("How many tests?")
numGrades = int(g)
grades = []*numGrades
for x in range(numGrades):
t = int(input("Enter Grade #" + str(x+1) + ": "))
grades.append(t)
avgGrades(grades)
def avgGrades(a):
total = 0
count = 0
for t in a:
total = total + t
count = count + 1
avg = total / count
print (f"average is: {avg}")
getGrades()

There is a statistics module which you can use:
import statistics
def get_grades_avg():
g = input("How many tests?")
num_grades = int(g)
grades = [] * num_grades
for x in range(num_grades):
grades.append(int(input("Enter Grade #" + str(x + 1) + ": ")))
return statistics.mean(grades)
avg = get_grades_avg()
print('avg: {}'.format(avg))

Using Python list is well. Maybe trying some built-in functions for getting average grade would be more easily.
Assume grades is a list store some grade.
sum(grades) / len(grades)

You can use something like this:
def average_factory():
count_numbers = 0
sum_numbers = 0
def wrapper(number):
nonlocal count_numbers
nonlocal sum_numbers
sum_numbers += number
count_numbers += 1
return sum_numbers / count_numbers
return wrapper
def get_number(message):
str_number = input(message)
try:
return int(str_number)
except (ValueError, TypeError):
print('Invalid number, please try again')
return get_number(message)
def get_average_of_all_tests():
count_tests = get_number('How many tests? ')
get_average = average_factory()
average = 0
for test_number in range(1, count_tests + 1):
number = get_number('Enter Grade #{test_number}: '.format(test_number=test_number))
average = get_average(number)
return average
Yes this solution seems a little complex with average factory. But I think storing all value just for calculating average is not so good idea. Storing only count and sum of grades is better.
If you have any question about solution feel free to ask me about it.

numpy or scipy offer good facilities for this.
store your numbers in an numpy.array([]).
To obtain your mean, numpy.mean(<yourarray>)
Your code would look like:
import numpy
import os
def getGrades():
g = input("How many tests?")
numGrades = int(g)
grades = []*numGrades
for x in range(numGrades):
t = int(input("Enter Grade #" + str(x+1) + ": "))
grades.append(t)
yourArray = numpy.array(grades)
return numpy.mean(yourArray)

Related

My assignment is to Create a file with comma seperated random numbers. Write python code to sum and average of them. How to do this?

n = ("random_numbers", "r+")
a = int(input("How many number do want to input? Type 0 to exit:"))
sum = 0
count = 0
number = 0
for i in range(a):
x = int(input("Enter a number:"))
n.write(str(x) + str(','))
sum = sum + number
count += 1
average = sum/count
n.write('the sum of the numbers is' + sum)
n.write('the average of the numbers is' + average)
n.seek(0)
n.read()
n.close()
This code when it is run shows the error: AttributeError: 'tuple' object has no attribute 'write'
you can use random.sample to generate your random numbers:
import random
a = int(input("How many number do want to input?"))
with open('my_file.txt', 'w') as fp:
my_numbers = random.sample(range(1000), a)
fp.write(','.join(map(str, my_numbers)))
fp.write( '\nthe sum of the numbers is ' + str(sum(my_numbers)))
fp.write( '\nthe average of the numbers is ' + str(sum(my_numbers) / len(my_numbers)))
in the above example if you have a > 1000 this code will not work, another way to generate your random numbers is:
import random
a = int(input("How many number do want to input?"))
with open('my_file.txt', 'w') as fp:
my_numbers = [random.randint(0, 1000) for _ in range(a)]
fp.write(','.join(map(str, my_numbers)))
fp.write( '\nthe sum of the numbers is ' + str(sum(my_numbers)))
fp.write( '\nthe average of the numbers is ' + str(sum(my_numbers) / len(my_numbers)))
using random.randint

numerology .. how to shorten code..?

I have written this code for finding the numerological value of a name. Is there any way in which i can shorten the code, or nest one loop inside the other?
alphabets = {"A":1,"I":1,"J":1, "Q":1,"Y":1,"B":2,"K":2,"R":3,"C":3,"G":3,"L":3,"S":3,"D":4,"M":4,"T":4,"H":5,"E":5,"N":5,"X":5,"U":6,"V":6,"W":6,"O":7, "Z":7,"P":8,"F":8}
word =input("your numerology score is :") #since i am using python 3 to code this
def digit_sum(n):
#prepare a list of numbers in n convert to string and reconvert
numbers=[]
for digit in str(n):
numbers.append(int(digit))
# add up the total of numbers
total=0
for number in numbers:
total += number
return total
def numerology(word):
total = 0
for letter in word.upper():
total += alphabets[letter]
total = digit_sum(total)
return total
print (numerology(word))
To understand what is meant by numerological value, please see https://en.wikipedia.org/wiki/Numerology#Latin_alphabet_systems.
alphabets = {"A":1,"I":1,"J":1, "Q":1,"Y":1,"B":2,"K":2,"R":3,"C":3,"G":3,"L":3,"S":3,"D":4,"M":4,"T":4,"H":5,"E":5,"N":5,"X":5,"U":6,"V":6,"W":6,"O":7, "Z":7,"P":8,"F":8}
name = "this is a sample name"
digits = str(sum([alphabets[l] for l in name.upper() if l in alphabets.keys()]))
numerological_value = int(digits) % 9
if numerological_value == 0:
numerological_value = 9
print(numerological_value)
Comprehensions allow you to have a short hand for creating various data types.
In this case you want to build generators.
This is as you don't need to build every number before reducing the list, to a single number.
Wrapping one in sum can allow you to significantly shorten digit_sum. Which can become:
def digit_sum(n):
return sum(int(digit) for digit in str(n))
You can also change numerology to be a little shorter, if you combine the addition and assignment.
def numerology(word):
total = 0
for letter in word.upper():
total = digit_sum(total + alphabets[letter])
return total
If you want, you can use functools.reduce to make this span a total of six lines.
def numerology(word):
return functools.reduce(
lambda a, b: sum(int(digit) for digit in str(a + b)),
(alphabets[letter] for letter in word.upper()),
0
)
One-liner for laughs.
alphabets = {"A":1,"I":1,"J":1, "Q":1,"Y":1,"B":2,"K":2,"R":3,"C":3,"G":3,"L":3,"S":3,"D":4,"M":4,"T":4,"H":5,"E":5,"N":5,"X":5,"U":6,"V":6,"W":6,"O":7, "Z":7,"P":8,"F":8}
print("Your numerology score is "+ str((int(sum([alphabets[l] for l in input("Type your name:").upper() if l in alphabets.keys()])) % 9) or 9))
this one !!!
a= input()
b= 0
c= len(a)
d= {"a":1, "b":2, "c":3, "d":4, "e":5, "f":6, "g":7, "h":8, "i":9, "j":10, "k":11, "l":12, "m":13, "n":14, "o":15, "p":16, "q":17, "r":18, "s":19, "t":20, "u":21, "v":22, "w":23, "x":24, "y":25, "z":26, " ":0}
for i in range(c):
b= b+d[a[i]]
print(b)
gematria
i'm sure you can chain the reducer functions a bit better but...
const charMap = {A:1, J:1, S:1, B:2, K:2, T:2, C:3, L:3, U:3, D:4,
M:4, V:4, E:5, N:5, W:5, F:6, O:6, X:6, G:7, P:7, Y:7, H:8,
Q:8, Z:8, I:9, R:9};
let name = prompt ("Type your name in CAPS"); //for example: TOM
let wordScore = Array.from(name).reduce((nameScore, element) => {
let curValue = charMap[element]
return (nameScore + curValue)
},0)
let finalScore = Array.from(String(wordScore), Number).reduce((score, element) => {
return score > 10 ? score + element : score
})
alert(finalScore)

How can I get the average of a range of inputs?

I have to create a program that shows the arithmetic mean of a list of variables. There are supposed to be 50 grades.
I'm pretty much stuck. Right now I´ve only got:
for c in range (0,50):
grade = ("What is the grade?")
Also, how could I print the count of grades that are below 50?
Any help is appreciated.
If you don't mind using numpy this is ridiculously easy:
import numpy as np
print np.mean(grades)
Or if you'd rather not import anything,
print float(sum(grades))/len(grades)
To get the number of grades below 50, assuming you have them all in a list, you could do:
grades2 = [x for x in grades if x < 50]
print len(grades2)
Assuming you have a list with all the grades.
avg = sum(gradeList)/len(gradeList)
This is actually faster than numpy.mean().
To find the number of grades less than 50 you can put it in a loop with a conditional statement.
numPoorGrades = 0
for g in grades:
if g < 50:
numPoorGrades += 1
You could also write this a little more compactly using a list comprehension.
numPoorGrades = len([g for g in grades if g < 50])
First of all, assuming grades is a list containing the grades, you would want to iterate over the grades list, and not iterate over range(0,50).
Second, in every iteration you can use a variable to count how many grades you have seen so far, and another variable that sums all the grades so far. Something like that:
num_grades = 0
sum_grades = 0
for grade in grades:
num_grades += 1 # this is the same as writing num_grades = num_grades + 1
sum_grades += sum # same as writing sum_grades = sum_grades + sum
Now all you need to do is to divide sum_grades by num_grades to get the result.
average = float(sum_grade)s / max(num_grades,1)
I used the max function that returns the maximum number between num_grades and 1 - in case the list of grades is empty, num_grades will be 0 and division by 0 is undefined.
I used float to get a fraction.
To count the number of grades lower than 50, you can add another variable num_failed and initialize him to 0 just like num_counts, add an if that check if grade is lower than 50 and if so increase num_failed by 1.
Try the following. Function isNumber tries to convert the input, which is read as a string, to a float, which I believe convers the integer range too and is the floating-point type in Python 3, which is the version I'm using. The try...except block is similar in a way to the try...catch statement found in other programming languages.
#Checks whether the value is a valid number:
def isNumber( value ):
try:
float( value )
return True
except:
return False
#Variables initialization:
numberOfGradesBelow50 = 0
sumOfAllGrades = 0
#Input:
for c in range( 0, 5 ):
currentGradeAsString = input( "What is the grade? " )
while not isNumber( currentGradeAsString ):
currentGradeAsString = input( "Invalid value. What is the grade? " )
currentGradeAsFloat = float( currentGradeAsString )
sumOfAllGrades += currentGradeAsFloat
if currentGradeAsFloat < 50.0:
numberOfGradesBelow50 += 1
#Displays results:
print( "The average is " + str( sumOfAllGrades / 5 ) + "." )
print( "You entered " + str( numberOfGradesBelow50 ) + " grades below 50." )

Find median and mode from .txt file Python 3.4.1

I am trying to determine the median and mode from a list of numbers in "numbers.txt" file.
I am EXTREMELY new to python and have ZERO coding experience.
This is what I have so far calculating mean, sum, count, max, and min but I have no idea where to go from here.
number_file_name = 'numbers.txt'
number_sum = 0
number_count = 0
number_average = 0
number_maximum = 0
number_minimum = 0
number_range = 0
do_calculation = True
while(do_calculation):
while (True):
try:
# Get the name of a file
number_file_name = input('Enter a filename. Be sure to include .txt after the file name: ')
random_number_count = 0
print('')
random_number_file = open(number_file_name, "r")
print ('File Name: ', number_file_name, ':', sep='')
print('')
numbers = random_number_file.readlines()
random_number_file.close
except:
print('An error occured trying to read', random_number_file)
else:
break
try:
number_file = open(number_file_name, "r")
is_first_number = True
for number in number_file:
number = int(number) # convert the read string to an int
if (is_first_number):
number_maximum = number
number_minimum = number
is_first_number = False
number_sum += number
number_count += 1
if (number > number_maximum):
number_maximum = number
if (number < number_minimum):
number_minimum = number
number_average = number_sum / number_count
number_range = number_maximum - number_minimum
index = 0
listnumbers = 0
while index < len(numbers):
numbers[index] = int(numbers[index])
index += 1
number_file.close()
except Exception as err:
print ('An error occurred reading', number_file_name)
print ('The error is', err)
else:
print ('Sum: ', number_sum)
print ('Count:', number_count)
print ('Average:', number_average)
print ('Maximum:', number_maximum)
print ('Minimum:', number_minimum)
print ('Range:', number_range)
print ('Median:', median)
another_calculation = input("Do you want to enter in another file name? (y/n): ")
if(another_calculation !="y"):
do_calculation = False
If you want to find the median and mode of the numbers, you need to keep track of the actual numbers you've encountered so far. You can either create a list holding all the numbers, or a dictionary mapping numbers to how often you've seen those. For now, let's create a (sorted) list from those numbers:
with open("numbers.txt") as f:
numbers = []
for line in f:
numbers.append(int(line))
numbers.sort()
Or shorter: numbers = sorted(map(int, f))
Now, you can use all sorts of builtin functions to calculate count, sum, min and max
count = len(numbers)
max_num = max(numbers)
min_num = min(numbers)
sum_of_nums = sum(numbers)
Calculating the mode and median can also be done very quickly using the list of numbers:
median = numbers[len(numbers)//2]
mode = max(numbers, key=lambda n: numbers.count(n))
Maybe there is a reason for it but why are you avoiding using the python libraries? Numpy and scipy should have everything you are looking for such a task.
Have a look at numpy.genfromtxt() , numpy.mean() and scipy.stats.mode().

making a basic multiplication program in python

The goal of the program is for it to multiply two random numbers less than 12 and for the user to guess the answer. So far i have this . . .
import random
g=0
while g<10:
variable_1 = random.randint (0,13)
variable_2 = random.randint (0,13)
answer = variable_1 * variable_2
guess = input("What is 'variable_1' x 'variable_2'?")
if guess == answer:
print "Correct!"
else:
print "Incorrect!"
The problem is the input box literally says "What is Variable_1 x Variable_2?". But, i want it to have the value of the variables in the input box. Is there a way to do this?
Try this instead:
guess = input("What is %d x %d?" % (variable_1, variable_2))
querystr="What is "+str(variable_1)+" x "+str(variable_2)+"?";
Then you can
guess=input(querystr);
from random import randint
def val(lo=1, hi=12):
return randint(lo, hi)
def main():
right = 0
reps = 10
for rep in range(reps):
v1, v2 = val(), val()
target = v1 * v2
guess = int(raw_input("What is {} * {}?".format(v1, v2)))
if guess==target:
print("Very good!")
right += 1
else:
print("Sorry - it was {}".format(target))
print("You got {} / {} correct.".format(right, reps))

Categories

Resources