0

Do you know how we can write a code in Python including a function that takes list and find out if it is arithmetic or geometric? I wrote a code but its just Boolean and doesn't say its arithmetic or geometric and also has an extra output.

L=[int(x) for x in input("please enter a list:").split()]

def Arithemetic(L):
  i=1
  if(L[0]+L[i]==L[i+1]):
    return True
  i+=1

def Geometric(L):
  i=1
  if(L[0]*L[i]==L[i+1]):
    return True
  i+=1

def IsArithemeticOrGeometric(L):
  if(Arithemetic(L)):
    print(Arithemetic(L))
  elif(Geometric(L)):
    print(Geometric(L))

print(IsArithemeticOrGeometric(L))
Nilou
  • 9
  • 6
  • Your implementation of the function `IsArithemeticOrGeometric` returns nothing, but it seems that you planned to return `True` or `False` here. Please correct the source code. Also your functions `Arithemetic` and `Arithemetic` can return True or nothing. It seems that you need to add `return False` at the end of both functions. – Ilya Apr 14 '17 at 10:47
  • Moreover, your `Arithemetic` and `Geometric` functions only test the case `i=1`: there is no loop to increment `i`. – Simpom Apr 14 '17 at 10:50
  • I'd do this for the arithmetic sequence: `all((i - j) == (j - k) for i, j, k in zip(l[:-2], l[1:-1], l[2:]))` –  Apr 14 '17 at 10:53
  • Have you studied loops yet? It is unlikely that looking at the first 3 elements (which is all your code does) is enough. Also -- you only return something *if* a condition is true, but return nothing otherwise. – John Coleman Apr 14 '17 at 11:21
  • A bit of a hint: your `L[0]+L[i]==L[i+1]` is equivalent to the condition `L[i-1]+L[i]==L[i+1]): ` (when `i` is 1). Once the condition is expressed purely in terms of `i` then you can check it in a loop, either returning `False` the first time it fails or returning `True` if you finish the loop with no counterexample found. Make sure you handle the case of lists of length < 2 adequately. There are other ways, but turning what you have into a loop in the most direct way will keep the work your own work. – John Coleman Apr 14 '17 at 11:34

1 Answers1

1

There are a few mistakes here, I will try to go over them one by one

Asking for the list

L=[int(x) for x in input("please enter a list:").split()]

This will throw a ValueError when it gets fed a non-numeric type. This will also round any float to int

Problem one can be solve by surrounding it with a while loop and a try-catch block

while True:
    try:
        L=[int(x) for x in input("please enter a list:").split()]
        break
    except ValueError:
        pass

The problem with the int can be easily solved by changing int(x) to float(x)

When using float, beware of the nature of floating point numbers

Checking for arithmetic and geometric

In your solution, i never gets incremented, so this only checks the first two values. Borrowing from @dex-ter's comment you can change this to

def is_arithmetic(l):
    return all((i - j) == (j - k) for i, j, k in zip(l[:-2], l[1:-1], l[2:]))

For an explanation why on how this works, check the background of list splicing and zip

For is_geometric you can easily adapt this solution.

This is also an excellent example where unittests would've made this error clear

assert is_geometric((1,2))
assert is_geometric((1,2, 4))
assert is_geometric((1,2, 4, 8))
assert not is_geometric((1,2, 4, 9))
try:
    is_geometric((1, 2, 'a'))
    raise AssertionError('should throw TypeError')
except TypeError:
    pass

The result

Your result only prints True or False is because that's what you tell your program to do. Your IsArithemeticOrGeometric() has no return statement, so it always returns None, which does not get printed. , so all the output comes from print(Arithemetic(L)) or print(Geometric(L))

A possible solution here would be something like this:

def is_arithmetic_or_geometric(l):
    if is_arithmetic(l):
        return 'arithmetic'
    if is_geometric(l):
        return 'geometric'

print(is_arithmetic_or_geometric(L))
Community
  • 1
  • 1
Maarten Fabré
  • 6,938
  • 1
  • 17
  • 36