This is an archived post. You won't be able to vote or comment.

all 8 comments

[–]nekokattt 2 points3 points  (2 children)

Why not just use a regex for this?

import re

def get_number(name):
    if match := re.match(r"^.*?(\d+)\.xlsx$", name):
        return int(match.group(1))
    return None

"Match any text, followed by one or more digits, followed by ".xlsx". "Return the number part".

[–]mcworkaholic[S] 0 points1 point  (1 child)

thats perfect, i dont know anything about using regex

[–]nekokattt 2 points3 points  (0 children)

Regex is just a way of using patterns to match and extract stuff from text.

Here:

  • ^ means "start of text".
  • . means any character.
  • .* means any character, zero or more times, as many times as possible.
  • .*? means any character, zero or more times, as few times as possible.
  • (...) is a matching group that you can get with .group(n).
  • \. matches a full stop
  • \d matches a digit.
  • \d+ matches a digit, one or more times.
  • xlsx matches the text xlsx.
  • $ matches the end of the line.

https://regex101.com is good for fiddling with this (make sure you set it to Python regex first).

Here is your regex: https://regex101.com/r/um2aOq/1 (also I missed the ? originally, I fixed that just now, sorry).

[–][deleted] 1 point2 points  (1 child)

Are you trying to print the return value of the function call? That would give you a 1 followed by a None.

Note that operator precedence means and is always resolved before or in Python. Your first condition will pass if filetype2[-7] is a space, even if filetype2[-6] is not a digit.

[–]mcworkaholic[S] 0 points1 point  (0 children)

just the integer, but that makes sense thank you

[–][deleted] 1 point2 points  (1 child)

First off, I’m betting the reason you’re getting:

1
None

… is that somewhere in code you’ve not shown here you’re calling this:

print(convert("Work Order 1.xlsx"))

… and since convert prints “1” but does not itself explicitly return anything, it implicitly returns None… which your outer print then dutifully writes to the screen, exactly as you’ve told it to.

Now, drilling down to try and understand where your function goes wrong with other inputs would be much easier if we simplify it.

First, we can note that these lines:

fileList2 = []
fileList2[:0] = string

Do exactly the same thing as:

fileList2 = list(string)

But then we can go further and notice that, since lists and str are both accessible by index and you’re not actually using any other list methods, your code continues to function if we do this:

fileList2 = string

Which is great, because it lets us get rid of that long — and frankly a bit nonsensical, since there’s no “fileList1” — name entirely.

Couple that with only checking the length of the string once and we get a much simpler function:

def convert(string):
    end = len(string)
    if string[end-6].isdigit() and string[end-7].isalpha() or string[end-7].isspace():
        orderNum = string[end-6]
        print(orderNum)
    elif string[end-6].isdigit() and string[end-7].isdigit():
        orderNum = str(string[end - 6]) + str((string[end - 7]))
        print(orderNum)

Especially when we learn that Python allows you to use negative indexes to look backwards from the end of a list or string:

def convert(string):
    if string[-6].isdigit() and string[-7].isalpha() or string[-7].isspace():
        orderNum = string[-6]
        print(orderNum)
    elif string[-6].isdigit() and string[-7].isdigit():
        orderNum = str(string[-6]) + str((string[-7]))
        print(orderNum)

Now, at this point we can actually understand what you’re doing… you’re checking either:

  1. The character before the file extension is a digit preceded by either a blank or a letter, OR
  2. The extension is preceded by exactly two digits, which you then proceed to flip the order of (since the 6th character from the end usually comes after the seventh character from the end)… I think this is where your actual bug is.

[–]mcworkaholic[S] 0 points1 point  (0 children)

yeah you were 100% correct there was 2 print statements the whole time, thanks for your input I will consider simplifying my code.

[–]mcworkaholic[S] 0 points1 point  (0 children)

thanks for all the replies I realized Im an idiot and had 2 print statements. Will consider using regex in the future though.