Python Forum
stopping number conversion before end
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
stopping number conversion before end
#1
this function gets a str that has decimal digit characters followed by one alphabetic character that indicates how to multiply the number those digits represent. so, the function converts the digits and uses the letter to determine the other number to multiply and returns the product. for example: timedelta('12m') -> 720. what i am looking for is a pythonic way to convert the digits. could it be int(s[:-1])?

i am accustomed to a function in C (strtol,strtoul) that converts until it hits a non-digit and stores a pointer to the non-digit (literally one past the last converted digit). if i need to handle a case where there may be more than 1 character after the digits the Python code above is not enough. is there something good in Python to do that?

in Python, a reference to a string (or anything) can only refer to the whole string (or whole thing), never to a part of it.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
I don't know a short-and-sweet method to do that. I would probably use a regex, since that easily stores the index of where it finds the first non-digit. But using something like itertools.takewhile or itertools.groupby with str.isdigit could also be used to split the string and rejoin the "integer" parts.


import re

s = "435xkb3"

if mo := re.match(r"(\d+)", s):   #Python 3.8 walrus operator.  Split into 2 lines for earlier versions.
    number = int(mo.group(1))
    print(f"The starting number is {number} and the rest begins at index {mo.end()}")
    print(f"the rest -> {s[mo.end():]}")
else:
    print(f"I couldn't find any integer at the start of the string")
Reply
#3
the varying case i have at the moment is either a letter or no letter at all, so the simple code for this case is to use a try/except. try int(s) and if i get ValuError do int(s[:-1]). actually, for this one i'm using float(). i'll post code shortly. im just playing around. a boring evening so i'm coding random stuff.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
import itertools


def to_int(text):
    units = {"m": 60, "h": 3600, "k": 1000}
    value = int("".join(itertools.takewhile(lambda s: s.isdecimal(), text)))
    unit = "".join(itertools.dropwhile(lambda s: s.isdecimal(), text)).strip()
    value *= units.get(unit, 1)
    return value
or with regex

import re


def to_int(text):
    units = {"m": 60, "h": 3600, "k": 1000}
    if match := re.search(r"(?P<value>\d+)\s*?(?P<unit>\w+)", text):
        result = match.groupdict()
        value = int(result["value"])
        value *= units.get(result["unit"], 1)
        return value
A function for floats needs a different regex.
It's not so easy to make a correct regex to parse all possible floats.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#5
i wish i could find something that would teach how to use regular expressions without using perl code.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#6
DeaD_EyE Wrote:It's not so easy to make a correct regex to parse all possible floats.
I have an old regex in my notes
r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?"
Reply
#7
Your regex is incomplete:

In [1]: import re                                                                                                            

In [2]: re.search(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?", "nan")                                                 

In [3]: float("nan")                                                                                                         
Out[3]: nan
This is nitpicking, but was in the past a big discussion why it's horrible to parse floats right with a regex.
The conclusion was: Don't ask for permission, ask for forgiveness.

But for this case, it's good enough. Working with dates should not result into a "nan" or "inf".
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  multiple number format conversion oli_action 4 2,595 Aug-11-2020, 05:10 AM
Last Post: perfringo
  Stopping a loop in another file catosp 4 2,695 Jun-15-2020, 02:45 PM
Last Post: catosp
  Help with Stopping a function after a timer SheeppOSU 0 1,943 Jan-28-2019, 10:13 PM
Last Post: SheeppOSU
  reading raw data until condition is met, then stopping unknowntothem 7 4,166 Sep-27-2018, 06:10 AM
Last Post: unknowntothem
  Stopping scheduler with condition j.crater 17 15,968 Jan-10-2017, 11:06 AM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020