I have a problem that I think is asking me to have a user enter a input into a array. I am having difficulties understanding this and any help would be appreciated.
The problem is as follows:
Design a program that lets the user enter the total rainfall for each of 12 months into an array. The program should calculate and display the total rainfall for the year, the average monthly rainfall, and the months with the highest and lowest amounts.
Here is what I have wrote so far:
def get_rainfall(a, b)
rain_array = []
rain_array.push(a => b)
puts rain_array
end
get_rainfall('january', 300)
Thanks for updating the question C_B.
I think the slight issue you're having here is between hashes and arrays.
Your current method results in the following:
#=> [{"january"=>300}, {"february"=>...}]
This happens because when you call rain_array.push(a => b), you're pushing a hash to the array each time in a => b.
It seems to me you'd be better suited storing the whole things as a hash, perhaps:
hash = {}
def get_rainfall(hash, key, value)
hash[key] = value
puts hash
end
get_rainfall(hash, 'january', 300)
# {"january"=>300}
get_rainfall(hash, 'february', 200)
#{"january"=>300, "february"=>200}
Hash you add more entries, they will be stored under the month as the key, with the rainfall as the value.
Alternatively, you could also push an array of arrays - to tweak your current method:
rain_array = []
def get_rainfall(array, a, b)
array.push([a, b])
puts array
end
get_rainfall(rain_array, 'january', 300)
# january
# 300
get_rainfall(rain_array, 'february', 200)
# january
# 300
# february
# 200
You'll notice I'm pulling the declaration of the array or hash to store the values outside of the method; without this, you'll lose access to it as soon as the method has run.
Hope that helps - happy to expand if you've any questions or queries. Let me know how you get on.
One more update based on a further comment about getting user input. Try the following to get you started:
hash = {}
def get_rainfall(hash, month)
puts "Please enter value for #{month}"
hash[month] = gets.chomp
puts hash
end
get_rainfall(hash, 'january')
I'll write my answer in simple script form to not over complicate what is being asked here.
The minimal approach is to not worry about month names for now and simply collect a list (array) of 12 values to do the calculations with.
rainfall = 1.upto(12).map do |month_nr|
# `print` and `puts` are practically the same with the only difference being
# that `puts` adds a newline character to the string if it doesn't have one
# output the question to the user
print "enter the rainfall for month #{month_nr}: "
# get the input from the user and convert it into an integer
gets.to_i # output the rainfall
end
puts "the total rainfall is: #{rainfall.sum}"
puts "the average rainfall is: #{rainfall.sum / rainfall.size}"
puts "the highest rainfall is: #{rainfall.max}"
puts "the lowest rainfall is: #{rainfall.min}"
If you care about month names you can do the following:
# create an array of all months
months = %w[January February March April May June July August September October November December]
# ask the user for each moth the amount of rainfall
rainfall = months.map do |month_name|
print "enter the rainfall for month #{month_name}: "
[month_name, gets.to_i] # output both the month name and the rainfall provided
end
# convert [['January', 123], ['February', 456], ...]
# to { 'January' => 123, 'February' => 456, ... }
rainfall = rainfall.to_h
puts "the total rainfall is: #{rainfall.values.sum}"
puts "the average rainfall is: #{rainfall.values.sum / rainfall.size}"
# search the key with the highest value
puts "the month with the highest rainfall is: #{rainfall.key(rainfall.values.max)}"
# search the key with the lowest value
puts "the month with the lowest rainfall is: #{rainfall.key(rainfall.values.min)}"
If anything is unclear have a look at the reference of the thing it is you have difficulty with. If it's still unclear ask away in the comments.
references:
String interpolation ("1 + 1 = #{1 + 1}")
Integer#upto
Enumerable#map
Kernel#print output to standard output without appending newline
Kernel#gets read from standard input
String#to_i
Kernel#puts output to standard output while appending a newline character (unless already present)
Array#sum
Array#size
Array#max
Array#min
%w array of strings
Array#to_h convert array to a hash
Hash#values
Hash#key
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
class SalesAgent
attr_accessor :sname, :stype, :samount
def initialize (name, type, amount)
#complete initialize() function
#sname = name
#stype = type
#samount = amount
end
end
def main
# create a new array
sale = Array.new
# repeat the following all the 4 sales agents
input = "Yes"
while input == "Yes"||input == "yes"
puts "Input agent name:"
# get input from user
sname = gets.chomp
puts "Input agent type (Junior/Senior):"
# get input from user
stype = gets.chomp
puts "Input sales made by this agent (RM):"
# get input from user (float type)
samount = gets.chomp.to_f
sales = SalesAgent.new(sname, stype, samount)
sale << sales
juniorsum(sales)
puts "Key-in another agent data ? (Yes/No)"
input = gets.chomp
end
# create the new SalesAgent object from the input above
# add the new SalesAgent object into the array
# call display() function
sale.each {|sales| display(sales)}
# call juniorsum() function
juniorsum(sales)
# print total sales made by all the junior sales agents
sleep(1)
puts "Total sales made by junior is RM " + juniorsum(sales).to_s
end
# This function receives an array as parameter
def display(sales)
puts "Name: #{sales.sname}"
puts "Sales: #{sales.samount.to_s}"
puts ""
#display names of all the sales agents and their individual sales amount
end
# This function receives an array as parameter
# It calculates and returns the total sales made by all the junior sales agents
def juniorsum(sales)
if sales.stype =="Junior"||sales.stype == "junior"
total = total = sales.samount
end
return total
end
main
It looks like your sales total method is only operating on one entry, not the list as I think you intend. Fixed it looks like:
def juniorsum(sales)
sales.select do |s|
s.stype.downcase == 'junior'
end.inject(0) do |sum, s|
sum + s.samount
end
end
Where that uses select to find all "junior" sales, then inject to sum up the samount values. This filter and reduce pattern is quite common, so it's worth studying and using whenever you're facing problems like this.
Note to call it you'll need to pass in the array, not a single entry:
puts "Total sales made by junior is RM #{juniorsum(sale)}"
Note you call that method twice, once for no reason. If you want to interpolate in a string use the #{...} interpolation method. No to_s required!
I'm an absolute beginner to Python and am tasked with creating a program that does a few things:
Inputs employee names into a list.
Inputs that employee's salary after inputting their name.
Totals the salaries in a list, (2 lists: names[] and salaries[]).
Finds the average salary after totaling.
Prints employees that earn within $5,000 of the average salary (Where I'm stuck).
Please see my code below:
# function to total the salaries entered into the "newSalary" variable and "salaries[]".
def totalSalaries(salaries):
total = 0
for i in salaries:
total += i
return total
# Finds the average salary after adding and dividing salaries in "salaries[]".
def averageSalaries(salaries):
l = len(salaries)
t = totalSalaries(salaries)
ave = t / l
return ave
# Start main
def main():
# Empty names list for "name" variable.
names = []
# Empty salaries list for "salary" and "newSalary" variables.
salaries = []
# Starts the loop to input names and salaries.
done = False
while not done:
name = input("Please enter the employee name or * to finish: ")
salary = float(input("Please enter the salary in thousands for " + name + ": "))
# Try/except to catch exceptions if a float isn't entered.
# The float entered then gets converted to thousands if it is a float.
try:
s = float(salary)
# Message to user if a float isn't entered.
except:
print("Please enter a valid float number.")
done = False
newSalary = salary * 1000
# Break in the loop, use * to finish inputting Names and Salaries.
if name == "*":
done = True
# Appends the names into name[] and salaries into salaries[] if * isn't entered.
# Restarts loop afterwards if * is not entered.
else:
names.append(name)
salaries.append(newSalary)
# STUCK HERE. Need to output Names + their salaries if it's $5,000 +- the total average salary.
for i in range(len(salaries)):
if newSalary is 5000 > ave < 5000:
print(name + ", " + str(newSalary))
# Quick prints just to check my numbers after finishing with *.
print(totalSalaries(salaries))
print(averageSalaries(salaries))
main()
Any info is greatly appreciated. I hope the rest of the functions and logic in this program makes sense.
Your haven't written your iterator correctly. With an array, you can just use for element in array: and the loop will iterate over array by putting each element in element. So your for loop becomes for salary in salaries.
Also, You need to split your condition in two and use additions and substractions. Your code should check if the salary is higher or equal to the average minus 5000 and if it is lower or equal to the average plus 5000. If you want to formalize this mathematically it would be:
Salary >= Average - 5000
and
Salary <= Average + 5000
So the condition at line becomes if salary >= (average - 5000) and salary <= (average + 5000)
Finally, you do not call averageSalaries before entering the loop, so the average salary haven't been computed yet. You should call the function and put the result in a variable before your for loop.
I want to accept (say)3 time elements (for example 8:30, 8:20 & 8:00) from user and store it in an array using 'datenum'. How can i achieve that? Please help.
Assuming that you just want to prompt the user given the current day and year and you only want the current time (hours and minutes - seconds is 0), you can do the following:
dateNumArray = []; %// Store datenums here
%// Enter a blank line to quit this loop
while true
timestr = input('Enter a time: ', 's');
if (isempty(timestr))
break;
end
%// Split the string up at the ':'
%//splitStr = strsplit(timestr, ':'); %// For MATLAB R2012 and up
splitStr = regexp(timestr, ':', 'split');
%// Read in the current date as a vector
%// Format of: [Year, Month, Day, Hour, Minute, Second]
timeRead = clock;
%// Replace hours and minutes with user prompt
%// Zero the seconds
timeRead(4:6) = [str2num(splitStr{1}) str2num(splitStr{2}) 0];
%// Convert to datenum format
dateNumArray = [dateNumArray datenum(timeRead)];
end
What the above code does is that we will keep looping for user input, where the time is expected to be in HH:MM format. Note that I did not perform error checking, so it is expected that HH is between 0-23 while MM is between 0-59. You keep putting in numbers by pushing in ENTER or RETURN for each entry. It parses this as a string, splits the string up at the : character, and converts each part before and after the : character into a number. We then get the current time when each hour and minute was recorded using the clock command. This is in a 6 element vector where the year, the month, the day, the hour, the minute and the second are recorded. We simply replace the hour and minute with what we read in from the user, and zero the seconds. We finally use this vector and append this to a dateNumArray variable where each time the user writes in a time, we will append a datenum number into this array.
When you call this, here is an example scenario:
Enter a time: 8:30
Enter a time: 8:45
Enter a time: 8:00
Enter a time:
Here's the example output from above:
format bank %// Show whole numbers and little precision
dateNumArray
format %// Reset format
dateNumArray =
735778.35 735778.36 735778.33
I'm having a lot of trouble dealing with with a particular question in my critical thinking class.
The task is this:
Task
Develop an algorithm to prompt for and obtain maximum daily temperatures for a whole year. However, in order to consider leap years, your algorithm should first prompt the user for the number of days in this particular year. That is, your algorithm should expect 365 or 366 as the first input number followed by input temperature values.
In addition, for this particular year, your algorithm must also determine and display the average, maximum, and minimum of these temperatures values.
Here's an example of what needs to happen:
Prompt for number of days in a year
(let's say they enter 365)
Then prompt user for MAXIMUM daily tempretures for 365 days.
Take those 365 (individual) maximum tempretures, find the lowest value that will = Min_temp.
Take those 365 (individual) maximum tempretures, find the highest value that will = Max_temp.
Sum up all 365 invidual max tempretures and divide it by the number of days in the year (365) = Avg_temp.
Print Min_temp
Print Max_temp
Print Avg_temp
So far this is what I have:
1. Prompt operator to enter Number_Of_Days within year.
2. WHILE Number_Of_Days = 365 or 366 THEN
3. IF Number_Of_Days is = 365 THEN
4. Year = 365
5. ELSEIF Number_Of_Days = 366 THEN
6. Year = 366
7. ENDIF
8. ELSEWHILE Number_of_Days is NOT = 365 or 366 THEN
9. Print ‘ERROR: Please enter a number that is 365 or 366.’
10. Prompt operator to enter Number_Of_Days within year.
11. ENDWHILE
12. DOWHILE MaxDayTemp = 1 to Year
16. Prompt operator for MaxDailyTemp
15. ENDO
From here we're meant to get an average of all the maximum temps provided by the user, that's easily done by AVG_TEMP = Sum of Temps / Days in the year.
What I can't work out is how to take the values of each day and find the lowest and highest values that are provided.
I've been trying to work it out with an array but I'm totally confused by it.
Please help! :(
I think you are expecting something like this, tried to use your conversion. Format it as you want.
i=0;
tempsum=0;
tempmax=0;
tempmin=100;
currenttemp=0;
no_days=0;
// variables used to store values
do
(prompt user for number of days)
no_days = user input
while no_days!=365 or no_days!=366 // will loop until user enter 365 or 366
while i<no_days
do
(Prompt operator for MaxDailyTemp)
currenttemp = userinput
while (currenttemp value is invalid) // thinking in the same way as above
if currenttemp > tempmax
tempmax = currenttemp
else if currenttemp < tempmin
tempmin = currenttemp
tempsum = tempsum + currenttemp
i = i+1
end
display average temp. = tempsum/no_days
display max temp. = tempmax
display min temp. = tempmin
I don't know what syntax is required for your class but this
max = (1 st value)
min = (1 st value)
i = 2
WHILE i < year THEN
IF (i th value) > max THEN
max = (i th value)
ELSIF (i th value) < min THEN
min = (i th value)
i = i + 1
would get the min and max value.
I have a large array with daily data from 1926 to 2012. I want to find out how many observations are in each year (it varies from year-to-year). I have a column vector which has the dates in the form of:
19290101
19290102
.
.
.
One year here is going to be July through June of the next year.
So 19630701 to 19640630
I would like to use this vector to find the number of days in each year. I need the number of observations to use as inputs into a regression.
I can't tell whether the dates are stored numerically or as a string of characters; I'll assume they're numbers. What I suggest doing is to convert each value to the year and then using hist to count the number of dates in each year. So try something like this:
year = floor(date/10000);
obs_per_year = hist(year,1926:2012);
This will give you a vector holding the number of observations in each year, starting from 1926.
Series of years starting July 1st:
bin = datenum(1926:2012,7,1);
Bin your vector of dates within each year with bin(1) <= x < bin(2), bin(2) <= x < bin(3), ...
count = histc(dates,bin);