Need to set the limits of input data - limit

Needing some help please with a project for a course that requires us to create a python program that has the user input 5 numbers (between 0 and 100), displays those numbers on the screen, then calculates and displays the sum of the numbers and average of those numbers. I have done pretty much everything except for having the program determine if the number is between 0 and 100 and if it isn't, prompt the user for a number within the range. Can anyone please help me with this last part. Here is the code I have at present.
print("please enter your 5 marks below")
#read 5 inputs
mark1 = int(input("enter mark 1: "))
mark2 = int(input("enter mark 2: "))
mark3 = int(input("enter mark 3: "))
mark4 = int(input("enter mark 4: "))
mark5 = int(input("enter mark 5: "))
#create array/list with five marks
marksList = [mark1, mark2, mark3, mark4, mark5]
#print the array/list
print(marksList)
#calculate the sum and average
sumOfMarks = sum(marksList)
averageOfMarks = sum(marksList)/5
#display results
print("The sum of your marks is: "+str(sumOfMarks))
print("The average of your marks is: "+str(averageOfMarks))
UPDATE: I have managed to figure it out using WHILE loops as below, however I am sure there is a much more efficient way of doing it by having just 1 input statement with a variable (say 'n') which loops through the numbers 1-5....any ideas on how to do that??
while True:
mark1 = int(input("enter mark 1: "))
if 0 < mark1 <100:
break
print('Please enter a number between 0 and 100')
while True:
mark2 = int(input("enter mark 2: "))
if 0 < mark2 <100:
break
print('Please enter a number between 0 and 100')
while True:
mark3 = int(input("enter mark 3: "))
if 0 < mark3 <100:
break
print('Please enter a number between 0 and 100')
while True:
mark4 = int(input("enter mark 4: "))
if 0 < mark4 <100:
break
print('Please enter a number between 0 and 100')
while True:
mark5 = int(input("enter mark 5: "))
if 0 < mark5 <100:
break
print('Please enter a number between 0 and 100')

Related

collatz sequence - try except; float number input

i was trying to make a simple collatz sequence with the following code
number = int(input("Please insert number: \n"))
def collatz():
if number % 2 == 0:
print(number // 2)
elif number % 2 == 1:
print(number * 3 + 1)
collatz()
so, if number is even, then collatz() should print number // 2 and return this value. If number is odd, then collatz() should print and return 3 * number + 1..
the excercise also asks me to implement try & except statements if the user inputs a float. My idea was as following:
number = int(input("Please insert number: \n"))
def collatz():
if number % 2 == 0:
print(number // 2)
elif number % 2 == 1:
print(number * 3 + 1)
try:
collatz()
except ValueError:
print(abs(number))
it doesn't work giving me
ValueError: invalid literal for int() with base 10: '1.2'
although the try except statement what am i doing wrong?

Is it better way to do that?

I wrote a simple script to sum all digits of positive integer input until 1 digit is left ( for example for input 12345 result is 6 because 1+2+3+4+5 = 15 and 1+5 = 6). It works but is it better way to do that? ( more correct?)
here is a code:
def sum(n)
string=n.to_s
while string.length > 1 do
result=string.chars.inject { |sum,n| sum = sum.to_i + n.to_i}
string=result.to_s
end
puts "Sum of digits is " + string
end
begin
p "please enter a positive integer number:"
number = Integer(gets.chomp)
while number<0
p "Number must be positive!Enter again:"
number = Integer(gets.chomp)
end
rescue
p "You didnt enter integer!:"
retry
end
sum(number)
According to Wikipedia, the formula is:
dr(n) = 1 + ((n − 1) mod 9)
So it boils down to:
def sum(n)
1 + (n - 1) % 9
end
To account for 0, you can add return 0 if n.zero?
You could use divmod (quotient and modulus) to calculate the digit sum without converting to / from string. Something like this should work:
def sum(number)
result = 0
while number > 0 do
number, digit = number.divmod(10)
result += digit
if number == 0 && result >= 10
number = result
result = 0
end
end
result
end
sum(12345) #=> 6
The line
number, digit = number.divmod(10)
basically strips off the last digit:
12345.divmod(10) #=> [1234, 5]
1234 becomes the new number and 5 is being added to result. If number eventually becomes zero and result is equal or greater than 10 (i.e. more than one digit), result becomes the new number (e.g. 15) and the loops starts over. If result is below 10 (i.e. one digit), the loop exits and result is returned.
Short recursive version:
def sum_of_digits(digits)
sum = digits.chars.map(&:to_i).reduce(&:+).to_s
sum.size > 1 ? sum_of_digits(sum) : sum
end
p sum_of_digits('12345') #=> "6"
Single call version:
def sum_of_digits(digits)
digits = digits.chars.map(&:to_i).reduce(&:+).to_s until digits.size == 1
return digits
end
It's looking good to me. You might do things a little more conscise like use map to turn every char into an integer.
def sum(n)
string=n.to_s
while string.length > 1 do
result = string.chars.map(&:to_i).inject(&:+)
string = result.to_s
end
puts "Sum of digits is " + string
end
You could also use .digits, so you don't have to convert the input into a string.
def digital_root(n)
while n.digits.count > 1
array = n.digits
n = array.sum
end
return n
end

All possible N choose K WITHOUT recusion

I'm trying to create a function that is able to go through a row vector and output the possible combinations of an n choose k without recursion.
For example: 3 choose 2 on [a,b,c] outputs [a,b; a,c; b,c]
I found this: How to loop through all the combinations of e.g. 48 choose 5 which shows how to do it for a fixed n choose k and this: https://codereview.stackexchange.com/questions/7001/generating-all-combinations-of-an-array which shows how to get all possible combinations. Using the latter code, I managed to make a very simple and inefficient function in matlab which returned the result:
function [ combi ] = NCK(x,k)
%x - row vector of inputs
%k - number of elements in the combinations
combi = [];
letLen = 2^length(x);
for i = 0:letLen-1
temp=[0];
a=1;
for j=0:length(x)-1
if (bitand(i,2^j))
temp(k) = x(j+1);
a=a+1;
end
end
if (nnz(temp) == k)
combi=[combi; derp];
end
end
combi = sortrows(combi);
end
This works well for very small vectors, but I need this to be able to work with vectors of at least 50 in length. I've found many examples of how to do this recursively, but is there an efficient way to do this without recursion and still be able to do variable sized vectors and ks?
Here's a simple function that will take a permutation of k ones and n-k zeros and return the next combination of nchoosek. It's completely independent of the values of n and k, taking the values directly from the input array.
function [nextc] = nextComb(oldc)
nextc = [];
o = find(oldc, 1); %// find the first one
z = find(~oldc(o+1:end), 1) + o; %// find the first zero *after* the first one
if length(z) > 0
nextc = oldc;
nextc(1:z-1) = 0;
nextc(z) = 1; %// make the first zero a one
nextc(1:nnz(oldc(1:z-2))) = 1; %// move previous ones to the beginning
else
nextc = zeros(size(oldc));
nextc(1:nnz(oldc)) = 1; %// start over
end
end
(Note that the else clause is only necessary if you want the combinations to wrap around from the last combination to the first.)
If you call this function with, for example:
A = [1 1 1 1 1 0 1 0 0 1 1]
nextCombination = nextComb(A)
the output will be:
A =
1 1 1 1 1 0 1 0 0 1 1
nextCombination =
1 1 1 1 0 1 1 0 0 1 1
You can then use this as a mask into your alphabet (or whatever elements you want combinations of).
C = ['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k']
C(find(nextCombination))
ans = abcdegjk
The first combination in this ordering is
1 1 1 1 1 1 1 1 0 0 0
and the last is
0 0 0 1 1 1 1 1 1 1 1
To generate the first combination programatically,
n = 11; k = 8;
nextCombination = zeros(1,n);
nextCombination(1:k) = 1;
Now you can iterate through the combinations (or however many you're willing to wait for):
for c = 2:nchoosek(n,k) %// start from 2; we already have 1
nextCombination = nextComb(A);
%// do something with the combination...
end
For your example above:
nextCombination = [1 1 0];
C(find(nextCombination))
for c = 2:nchoosek(3,2)
nextCombination = nextComb(nextCombination);
C(find(nextCombination))
end
ans = ab
ans = ac
ans = bc
Note: I've updated the code; I had forgotten to include the line to move all of the 1's that occur prior to the swapped digits to the beginning of the array. The current code (in addition to being corrected above) is on ideone here. Output for 4 choose 2 is:
allCombs =
1 2
1 3
2 3
1 4
2 4
3 4

script for calculating boundaries between elements of matrix

The following script gives me sum of boundaries of each element of matrix. boundaries are calculated about elements with value 1 that are next to each other. product of this summation named contact perimeter.
but Is there any other way that I can summarize or vectorize my raw and simple script?
I ask this request because my real matrix is very large and use of "for" increase the time of calculation.
Thank you.
a1=[1 1 0 1 0 1;
0 1 1 0 0 1;
1 1 0 1 0 1;
1 1 0 0 1 0;
0 0 0 1 1 1]
m=5
n=6
cmp=zeros(m,n)
cmp1=zeros(m,n)
for i=1:m-1
for j=1:n
if a1(i,j)==a1(i+1,j) && a1(i,j)==1
cmp(i,j)=1
end
end
for i=1:m
for j=1:n-1
if a1(i,j)==a1(i,j+1) && a1(i,j)==1
cmp1(i,j)=1
end
end
end
end
cmtotal=cmp+cmp1
pc=sum(sum(cmtotal))
This should be pretty efficient one -
%// Case1 and case 2 matches
case1_matches = a1(1:end-1,:) == a1(2:end,:) & a1(1:end-1,:)==1
case2_matches = a1(:,1:end-1) == a1(:,2:end) & a1(:,1:end-1)==1
%// Get sum of those matches for the final output, equivalent to your pc
out = sum(case1_matches(:)) + sum(case2_matches(:))
You can replace the sum(..(:)) with nnz(), but I doubt that it will be any better than sum in terms of runtime performance in accordance with benchmarks of sum against nnz.

Why Can't This Code Find Powers? (Ruby)

App Academy's practice test says their chosen way of finding if an input is a power of 2 is to keep dividing it by 2 on a loop and check whether the end result is 1 or 0 (after having tested for the numbers 1 and 0 as inputs), which makes sense, but why won't this way work?
def try
gets(num)
counter = 0
go = 2 ** counter
if num % go == 0
return true
else
counter = counter + 1
end
return false
end
I can't figure out why this won't work, unless the counter isn't working.
There are a number of problems with your code.
First of all, there is no loop and your counter will reset to zero each time if you intend to use the method in a loop, because of counter = 0.
counter = 0; go = 2 ** counter basically means go = 2 ** 0 which is 1. Therefore num % 1 will always be 0
You actually need to divide the number and change it in the process. 12 % 4 will return 0 but you don't know by that if 12 is a power of 2.
IO#gets returns a string and takes a separator as an argument, so you need to use num = gets.to_i to actually get a number in the variable num. You are giving num to gets as an argument, this does not do what you want.
Try:
# Check if num is a power of 2
#
# #param num [Integer] number to check
# #return [Boolean] true if power of 2, false otherwise
def power_of_2(num)
while num > 1 # runs as long as num is larger than 1
return false if (num % 2) == 1 # if number is odd it's not a power of 2
num /= 2 # divides num by 2 on each run
end
true # if num reached 1 without returning false, it's a power of 2
end
I add some checks for your code. Note, that gets(num) returns a String. Your code is fine, but not for Ruby. Ruby hates type-cross-transform like Perl does.
def try(num = 0)
# here we assure that num is number
unless (num.is_a?(Integer))
puts "oh!"
return false
end
counter = 0
go = 2 ** counter
if num % go == 0
return true
else
counter = counter + 1
end
return false
end
The general problem is "how string could use '%' operator with number?"
Try some code in the interpretator (irb):
"5" % 2
or
"5" % 0

Resources