1

I'm trying to write a program that will calculate the LCM of up to five numbers.
I've written this code so far:

a = b = True
while a == True:
    x = input('\nEnter two to five numbers separated by commas: ').split(',')
    if x.index(0) == True:
        print('\nNo zeroes.')
    if len(x) < 2:
        while b == True:
            x.append(input('\nTwo numbers are needed. Enter one more: '))
            b = False
    if len(x) > 5:
        print('\nDon\'t enter more than five numbers.')
        continue
    a = False

When I try to run the code I get this error:

Enter two to five numbers separated by commas: 0
Traceback (most recent call last):

  File "/home/mint/.config/spyder-py3/lcm.py", line 4, in <module>
    if x.index(0) == True:

ValueError: 0 is not in list

How is this possible? My input was 0.

solid.py
  • 2,782
  • 5
  • 23
  • 30
Kos
  • 83
  • 8
  • 1
    Your input is a string. You need to convert your split elements to integers. e.g. `x=[int(i) for i in input('\nEnter two to five numbers separated by commas: ').split(',')]` – dspencer Mar 16 '20 at 09:45
  • 1
    Because `x` is a list of `string`, not `integer`. I haven't checked but it might work `x.index('0')` – You're awesome Mar 16 '20 at 09:45
  • @ You're awesome worked like a charm. Thank you. What exactly did I accomplish with this though? I'm new to Python and programming in general so pardon my ignorance. EDIT: It won't work when I input any other number though. – Kos Mar 16 '20 at 09:48
  • just to be clear, `if x.index(0)==True` you wanna check number 0 in x or not? – You're awesome Mar 16 '20 at 09:53
  • @dspencer I did what you suggested but saw no different outcome. – Kos Mar 16 '20 at 09:54
  • @Kos Have you tried printing `x` so you can see what it looks like? – dspencer Mar 16 '20 at 09:54
  • @You'reawesome what I want to do is to prevent any input of zero or negative number. So i want to check if any of the numbers i entered in x are zero or negatives. – Kos Mar 16 '20 at 09:55
  • @dspencer Just did that. I entered 0 and 6 and this was the output: Enter two to five numbers separated by commas: 0 [0] Two numbers are needed. Enter one more: 6 – Kos Mar 16 '20 at 09:58
  • @Kos You would also need to convert this `input('\nTwo numbers are needed. Enter one more: ')` to int. – dspencer Mar 16 '20 at 10:00

3 Answers3

3

Because x is a list of string not integers. To do your check, you can convert x to list of integers.

a=b=True
while a:
    # Map x to list of integers
    x = list(map(int, input('\nEnter two to five numbers separated by commas: ').split(',')))   
    # Check if there is zero or any negative number in x.
    if len(list(filter(lambda e: e <= 0, x))) > 0:
        print('\n No zeroes or negative numbers')
        continue
    if len(x)<2:
        while b==True:
            x.append(input('\nTwo numbers are needed. Enter one more: '))
            b=False
    if len(x)>5:
        print('\nDon\'t enter more than five numbers.')
        continue
    a=False
You're awesome
  • 301
  • 2
  • 16
1

Maybe something like this, might be suitable for your purposes:

from functools import reduce
from math import gcd

x = []
while len(x) < 2 and len(x) <= 5: # Using this condition removes unneccesary break code:
    x = [int(i) for i in input('\nEnter two to five numbers separated by commas: ').split(',')]
    if x[0] == 0:
        print('\nNo zeroes.')
    if len(x) > 5:
        print('\nDon\'t enter more than five numbers.')
    if len(x) < 2:
        x.append(int(input('\nTwo numbers are needed. Enter one more: ')))

lcm = reduce(lambda x, y: x * y // gcd(x, y), x) # lcm = x * y / gcd(x, y)
print(lcm)

When run this prints the lcm, of the 5 inputted numbers.

Enter two to five numbers separated by commas: 1, 2, 3, 4, 5
60
solid.py
  • 2,782
  • 5
  • 23
  • 30
  • Yup it works great. Thank you. I wanted to write code without using anything from import though. It's a practice problem from a book I'm studying. – Kos Mar 16 '20 at 10:07
  • If you do it for me it defeats the purpose of learning the language. I do thank you for offering though. – Kos Mar 16 '20 at 10:12
  • @Kos If you wanna take a look here is the implementation of `reduce` https://docs.python.org/3/library/functools.html#functools.reduce and a sample implementation of `gcd` https://stackoverflow.com/questions/11175131/code-for-greatest-common-divisor-in-python – solid.py Mar 16 '20 at 10:18
  • @Kos the `lambda` function hosts the lcm for two numbers, and `reduce` applies that for each pair of numbers using the previous result of the calculation as seen in https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.python-course.eu%2Fpython3_lambda.php&psig=AOvVaw0BuJbqpAo9dRLj4PKrc0fz&ust=1584440428561000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCLjgvtrinugCFQAAAAAdAAAAABAN – solid.py Mar 16 '20 at 10:18
1

you can do first the prime factorization then compute the LSM:

from collections import Counter, defaultdict
from functools import reduce

def prime_factors(n):
    primes = []

    i = 2
    while n > 1:
        while n % i == 0:
            n = n / i
            primes.append(i)
        i = i + 1
    if primes:
        return primes

    return [n] # if n is a prime

def lcm(my_list):
    f = [Counter(prime_factors(e)) for e in my_list]

    lcm_primes =  Counter()
    for d in f:
        for prime, count in d.items():
            lcm_primes[prime] = max((lcm_primes[prime], count))

    return reduce(lambda x, y: x * (y[0] ** y[1]),  lcm_primes.items(), 1)

lcm([3, 15, 9, 6, 2])

output:

90
kederrac
  • 16,819
  • 6
  • 32
  • 55