Arijeet Acharyya
Arijeet Acharyya

Reputation: 73

How to include a lot of decision making loops for checking a number within a range in a correct way?

I am trying to solve a question to generate a list of numbers from a given range by making each number passed through a set of rules to get that number added in the list. Also to find the maximum element from the list.

This is the actual question: Write a python program which finds the maximum number from num1 to num2 (num2 inclusive) based on the following rules.

  1. Always num1 should be less than num2
  2. Consider each number from num1 to num2 (num2 inclusive). Populate the number into a list, if the below conditions are satisfied a)Sum of the digits of the number is a multiple of 3 b)Number has only two digits c)Number is a multiple of 5
  3. Display the maximum element from the list

In case of any invalid data or if the list is empty, display -1.

First of all, I am new to Python and not familiar to solve these type of complex problems. So I think I made a lot of silly mistakes.

def find_max(num1, num2):

    max_num=-1
    num_list=[] #list declared
    if(num1<num2): #to check num1 < num2 as said in the question
        for numbers in range(int(num1),int(num2)+1): #for numbers from the range
            tot=0
            count=0
            while(numbers>0): 
                digit=numbers%10
                tot=tot+digit #to generate sum of digits
                numbers=numbers//10 
                count=count+1 #to count the number of digits
                if(tot%3==0 and count==2 and numbers%5==0): 
                    num_list.append(numbers) #to generate the list
                else:
                    print(-1)
    else:
        print(-1)
    max_num = max(num_list) #to find the maximum value in the list
    return max_num

#Provide different values for num1 and num2 and test your program.
max_num=find_max(10,15)
print(max_num)

Results I am getting : -1 -1 -1........

Upvotes: 1

Views: 4506

Answers (4)

user13812082
user13812082

Reputation: 1

def find_max(num1, num2):

max_num=-1
num_list=[] 
if(num1<num2): 
    for numbers in range(int(num1),int(num2)+1): 
        tot=0
        count=0
        while(numbers>0): 
            digit=numbers%10
            tot=tot+digit 
            numbers=numbers//10 
            count=count+1
            if(tot%3==0 and count==2 and numbers%5==0): 
                num_list.append(numbers) 
            else:
                print(-1)
else:
    print(-1)
max_num = max(num_list) 
    return max_num

max_num=find_max(10,15)
print(max_num)

Upvotes: -1

def find_max(num1, num2):
if (num1<num2):


    max_num=-1
    for i in range(num1,num2 + 1,1):
        if (10 <= i <= 99 or -99 <= i <= -10):
            j = i/10
            k= i%10
            if ((j+k)%3==0 and i%5 == 0):
                max_num = i
# Write your logic here
    return max_num
else:
    return -1

#Provide different values for num1 and num2 and test your program. max_num=find_max(-100,500) print(max_num)

Upvotes: 0

Iulian
Iulian

Reputation: 300

Your function is not working like you want because you are using numbers for checking condition, but you're changing it in your code when you are making computations.

numbers = numbers // 10

So when you'll use it in if block, numbers will have a different value not the initial one. For example with numbers = 15 at the start it will become:

numbers -> 15 -> 1 -> 0

Thus when you check numbers % 5 == 0 it will never pass and the if conditional will fail. Use a copy of the number and every thing will work fine.

Revisited code:

def function_name(num1,num2):
  num_list=[] #list declared

  if(num1<num2): #to check num1 < num2 as said in the question
      for numbers in range(int(num1),int(num2)+1): #for numbers from the range
        tot=0
        count=0
        copy = numbers
        while(copy>0): 
            digit=copy%10
            tot=tot+digit #to generate sum of digits
            copy = copy//10 
            count = count+1 #to count the number of digits
            if(tot%3==0 and count==2 and numbers%5==0): 
                num_list.append(numbers) #to generate the list
            else:
                print(-1)
  else:
      print(-1)
  if num_list:#if the list is populates with some numbers
    return max(num_list)
  else: return "what you think is needed in case there aren't numbers" #None is a good choice equivalent to null in other programming languages

print(function_name(10,15))

My idea to implement your function

Not the best, but its shorter and more readable.

def function_name(num1,num2):
  num_list=[] #list declared

  if(num1<num2): #to check num1 < num2 as said in the question
      for number in range(int(num1),int(num2)+1): #for numbers from the range

        # for every char return its int and group all in a list
        # [int(digit) for digit in str(number)]
        tot = sum( [int(digit) for digit in str(number)])

        #count how many char are that is like saying how many digits
        count= len(str(number)) 

        if(tot%3==0 and count==2 and number%5==0): 
            num_list.append(number) #to generate the list
        else:
            print(-1)
  else:
      print(-1)
  if num_list:#if the list is populates with some numbers
    return max(num_list)
  else: 
    return "what you think is needed in case there aren't numbers" #None is a good choice equivalent to null in other programming languages

print("Max", function_name(10,15))

Upvotes: 1

tfpf
tfpf

Reputation: 682

The mistake in your code is that in your 'while' loop, you're modifying the value which is being checked for the conditions. (lulian has explained this well.)

Actually, your code can be rewritten more simply. You have these requirements. (a) Sum of the digits of the number is a multiple of 3. (b) Number has only two digits (c) Number is a multiple of 5.

Requirements (a) and (c) can be combined into a single requirement: if you know middle school mathematics, (a) basically means that the number itself is divisible by 3, and (c) means that it is divisible by 5. Together, they mean that the number should be divisible by 3 times 5, i.e. 15. We can exploit this property.

Let us revisit the problem. Observe that each time invalid data is detected, I use a return statement.

def find_max(num1, num2):

    # check for invalid data: 'num1' and 'num2' should be integers
    if type(num1) != int or type(num2) != int:
        return -1

    # check if 'num1' is greater than 'num2'
    if num1 > num2:
        return -1

    # initialize empty list
    num_list = []

    # find the nearest multiple of 15 to 'num1'
    if num1 % 15 == 0:
        nearest_multiple = num1
    else:
        nearest_multiple = num1 + 15 - num1 % 15

    # scan through possible numbers from 'nearest_multiple' to 'num2'
    for numbers in range(nearest_multiple, num2 + 1, 15):
        if 10 <= numbers <= 99 or -99 <= numbers <= -10:
            num_list.append(numbers)

    # if no valid number was detected, the list will remain empty
    if num_list == []:
        return -1

    return max(num_list)

Explanation: First, locate the nearest multiple of 15 greater than or equal to num1. So, if num1 is 15, then nearest_multiple is also 15. But if num1 were 21, then nearest_multiple would be 30. (The formula used is pure math.) Then, we iterate from nearest_multiple to num2 in jumps of 15. That way, we encounter only numbers which satisfy both (a) and (c). Then we check the number we encounter for condition (b).

Upvotes: 1

Related Questions