1

I am trying to iterate over the input strings below. If I encounter a float or an int, I want to push the element to a stack. When I encounter an operator "+-/*" or parentheses "()" or an "=", I perform other operations. The trouble that I have is identifying the floats or ints. People have suggested regex to break these into a list of strings, but I still have the problem of identifying these items as a float or int. I've tried isinstance() and that doesn't work either.

inputs:

theInput1 = "3.2+.4*5.67/6.145="
theInput2 = "11.897/3.4+9.2-0.4*6.9/12.6-16.7="
theInput3 = "234+34*65="
theInput4 = "(12+3)*(56/2)/(34-4)="

Something that I have tried that didn't work. (I'm appending to a list to simulate pushing to a stack so that I don't have to cut/paste the entire stack class here.)

s = "3.2+.4*5.67/6.145="

list = []

for i in s:
  if isinstance(i, float) == True or isinstance(i,int) == True:
    list.append(i)

print(list)
Yogesh Riyat
  • 129
  • 1
  • 7

5 Answers5

2

The first thing you should do is extract all the numbers (floats or ints) from the list. A great way to do this is using regex:

import re
input = '11.897/3.4+9.2-0.4*6.9/12.6-16.7='
nums = re.findall('([0-9.]+)', input, re.DOTALL)

More info found here: https://stackoverflow.com/a/7725094/14362052

Then we can iterate through them and convert them to floats:

nums = [float(num) for num in nums]

The reason your instanceof solution didn't work is because all the items in a string are characters which would never be of types float or int. Additionally, it would cut up numbers like 3.21 into 3, ., 2, 1, so we wouldn't know whether its 3.2 and 1 separate or 3.21.

Let me know if you have any questions :)

mushycow
  • 86
  • 2
  • This is a much better and cleaner method than mine lmao. – Buddy Bob Apr 25 '21 at 04:35
  • Lmao its aight. #regexgang – mushycow Apr 25 '21 at 04:49
  • 1
    This is great, but I'm not really looking to generate lists of floats and ints. I'm looking to iterate, identify what the element is (float, int, operator, paretheses etc.) and then do something. The operators and other items are easy because you can just see if its in "+-/" or "()". So I'm wondering if there is a way to put what you did into a for/if loop to iterate over the post regex string...I hope that makes sense! – Yogesh Riyat Apr 25 '21 at 04:59
  • I think what you want to do is always convert to float and use the `float.is_integer()`. This will return a boolean of True if it is convertable to an integer. – astrochun Apr 25 '21 at 05:10
  • 1
    @astrochun would you mind showing that in code? – Yogesh Riyat Apr 25 '21 at 05:14
  • 1
    Yes, I was working on an answer. See below. – astrochun Apr 25 '21 at 05:19
  • 1
    I would also avoid using the variable `input`. It conflicts with the built-in `input` function. – astrochun Apr 25 '21 at 05:22
  • @astrochun thanks! check out the answer I just posted as well. I've never used the function you mentioned so I'm looking forward to your answer. – Yogesh Riyat Apr 25 '21 at 05:22
1

Borrowing from mushycow re approach:

import re


def re_handling(input_str):
    print(f"Interpreting {input_str}")
    numbers_list = []
    nums = re.findall('([0-9.]+)', input_str, re.DOTALL)

    for num in nums:
        if float(num).is_integer():
             numbers_list.append(int(num))
        else:
             numbers_list.append(float(num))

    return numbers_list

theInput1 = "3.2+.4*5.67/6.145="
theInput2 = "11.897/3.4+9.2-0.4*6.9/12.6-16.7="
theInput3 = "234+34*65="
theInput4 = "(12+3)*(56/2)/(34-4)="

print(re_handling(theInput1))
print(re_handling(theInput2))
print(re_handling(theInput3))
print(re_handling(theInput4))

Outputs:

Interpreting 3.2+.4*5.67/6.145=
[3.2, 0.4, 5.67, 6.145]
Interpreting 11.897/3.4+9.2-0.4*6.9/12.6-16.7=
[11.897, 3.4, 9.2, 0.4, 6.9, 12.6, 16.7]
Interpreting 234+34*65=
[234, 34, 65]
Interpreting (12+3)*(56/2)/(34-4)=
[12, 3, 56, 2, 34, 4]
astrochun
  • 1,642
  • 2
  • 7
  • 18
  • 1
    I wasn't sure what else you wanted to do but this is just an if/else to illustrate that the separation of int vs float after you separate out the operators. – astrochun Apr 25 '21 at 05:20
  • @yogesh-riyat I modified to do the list append in my answer. – astrochun Apr 25 '21 at 05:31
0

I see what you mean. You can't really use isinstance in this case. Instead, you need to check the type of each number but type()won't work because it will always return a string.

So here is a weird but successful method of doing so.

import re
theInput1 = "3.2+.4*5.67/6.145="
theInput1 = re.split('\+|\*|\-|=|\/',theInput1)[:-1]
numbers = []
for number in theInput1:
    if str(float(number)) == number:numbers.append(float(number))
    elif str(int(float(number))) == number:numbers.append(int(float(number)))

output

[3, 5.67, 6.145]
Buddy Bob
  • 5,829
  • 1
  • 13
  • 44
0

I built on the answer from @mushycow, but I'd love to see if anyone can come up with anything cleaner!

import re
input = '11.897/5+9.2-0.4*6.9/13-16.7='
nums = re.findall('([0-9.]+)', input, re.DOTALL)
list = []
for i in nums:
  if '.' in i:
    list.append(float(i))
  else:
    list.append(int(i))
  
print(list)

for my use case it the list.append() will actually be stack.push(float(i)) or stack.push(int(i).

Yogesh Riyat
  • 129
  • 1
  • 7
-1

Please try this code:

dataStr = "11.897/3.4+9.2-0.4*6.9/12.6-16.7="

list = []

number = ''
for ch in dataStr:
    if ch.isdigit() or ch == '.':
        number +=ch
    else:
        list.append(number)
        number = ''
        # do other thing
        print(ch)

print(list)

Result:

/
+
-
*
/
-
=
['11.897', '3.4', '9.2', '0.4', '6.9', '12.6', '16.7']
timhu
  • 98
  • 4