Regular expression between two integers - python

I'm trying to build a regular expression that will match the word mark to an integer greater or equal to 140000 and less than or equal to 150000.
So, for example, the minimum value would be mark_140000 and the maximum value would be mark_150000. The values mark_139999 and mark_150001 would be invalid.
I have a method that will match from 140000 to 149999:
"^mark_14[0-9]{4}$"
How can I get the maximum to include 150000?

simple enough, just create 2 cases:
"^mark_(14[0-9]{4}|150000)$"

Your regex needs to account for all the possibilities of 140000 to 150000
^mark_1(4\d{4})|(50{4})

You could write a small function that checks if the number part is in the range:
import re
data = """So for example the minimum value would be mark_140000 and the maximum value would be mark_150000. The values mark_139999 and mark_150001 would be Many thanks and mark_100000000000000"""
rx = re.compile(r'mark_(\d+)')
def check(number):
number = float(number)
if 140000 <= number <= 150000:
return True
return False
matches = [match.group(0)
for match in rx.finditer(data)
if check(match.group(1))]
print(matches)
This yields
['mark_140000', 'mark_150000']

Related

Attempting to make a special counter

In Python I'm attempting to make a product_ID generator, which takes a number of any value and converts it into a hexadecimal format of "#AA0000". When the 4 numbers overflow past 9999, they increment the first letter by one in the ASCII uppercase set. Meaning if I give 10000 as input, I get #AB0001.
Currently I am using the modulus operator (%) to find the remainder of the input number so it is always within 4 digits. (For reference, the formula I used was Numb%9999.)
The issue I am currently having with is getting the second letter to increment properly. I've managed to get a single letter version working, which you can see here:
from string import ascii_uppercase as upper
upper = [a for a in upper]
def Convert_Numb_To_Ref(Order_Number):
"""Takes an Order_Number (int), and converts it into a unique Order_ID"""
Number = str((Order_Number%9999)+1) # Makes it so it never is bigger than 4 digits
Number = ("0"*(4-len(str(Number))))+Number # If number < 1000, adds on 0s to the beginning, so 1 -> 0001
try:
Letter = upper[Order_Number//9999] # Divides and floors
except IndexError:
print("Number too large! Cannot generate Product_ID")
return False
return f"#{Letter}{Number}"
If I was to input 10000, I would get #B0002.
This works fine, returning what I want to see. (Currently the above code only works with a single letter, which is why there aren't 2.) I'm just stuck with incrementing the second letter.
The problem is in this line:
Letter = upper[Order_Number//9999] # Divides and floors
If the order number becomes too large, the index becomes larger than 25, so you would get an IndexError. To avoid this, you should use "modulo 26" to get a number lower than 26. And you should do another lookup for the next letter (the left one).
Some other remarks:
To separate the high part and the low part you should not divide by 9999 but by 10000 (idem for the module operation), unless you want to skip the number 9999 (or 0000). This is not entirely clear from your question.
For the digits you can use standard Python formatting: '%04d' % nr will do the trick.
Putting it together you could write something like this:
import string
def number_to_reference(order_number):
"""Take an order number and convert it into a unique order id."""
if order_number >= 26 * 26 * 10000:
print("Number too large! Cannot generate Product_ID")
return False
# NB: You could also do the following instead:
# raise ValueError('Number too large! Cannot generate Product_ID')
high_part = order_number // 10000
low_part = order_number % 10000
letter1 = string.ascii_uppercase[high_part // 26]
letter2 = string.ascii_uppercase[high_part % 26]
return '#%s%s%04d' % (letter1, letter2, low_part)
print(number_to_reference(1)) # AA0001
print(number_to_reference(123)) # AA0123
print(number_to_reference(9999)) # AA9999
print(number_to_reference(10000)) # AB0000
print(number_to_reference(1234567)) # ET4567
print(number_to_reference(6759999)) # ZZ9999
print(number_to_reference(6760000)) # Number too large! Cannot generate Product_ID

How to generate certain length Credit Card number with prefix?

Trying to generate a certain length credit card number with a prefix given.
while len(str(cc_number)) < (len(str(length)) - 1):
digit = str(random.randrange(0, 9))
cc_number = str(cc_number) + str((digit))
return cc_number
I'm expecting to get say 16 digits long number with a variable size prefix given. How do i make this piece of code generate a right size string of numbers? This code by the way only concatenates 1 random digit to the end of the string... So i expect to get '4349578451278456', but the actual output is '41'
If length is 16, str(length) will give you the string '16' which has a len of 2. Just use length without len or str.
Beyond that, your return statement should be outside of the loop
Since you're already using the random module, I just want to offer an alternative solution:
from random import choices
from string import digits
cc_digits = choices(digits, k=16)
cc_number = "".join(cc_digits)
print(cc_number)

Take out numbers from String without list

I have to make a (def) program using Python language where user inserts a string ( up to 8 digits numbers (0-9) and letters (a-z) together), program has to find out how many numbers are there in a string. Program will calculate the sum and average of those numbers.
Approach 1 : Pure implementation by string, without using list at all.
def sum_and_average(string):
COUNT = 0
SUM = 0
for value in string:
if value.isdigit():
SUM += int(value)
COUNT +=1
print('Sum :',SUM)
print('Average :',SUM/COUNT)
Approach 2 : Using List Comprehensions and Ascii values
def sum_and_average2(s):
L = [int(var) for var in s if 48<=ord(var)<=57]
print('Sum :', sum(L))
print('Average :', sum(L)/len(L))
Approach 3 : Using Regex, Already Mentioned However Regex will also store values as list object so in your case approach 1 would be best but approach 3 will be fastest in case of long string input.
you can use regular expression to parse the spring to get your numbers and letters separately and then perform the required operation on the numbers.
Example
import re
def spring_program(spring):
regex = re.compile("([0-9]+)([a-z]+)")
numbers = regex.match(spring).group(1)
letters = regex.match(spring).group(2)
print(numbers)
print(letters)
#you can now do any manipulation to the numbers

Alphanumeric sorting in Python and negative numbers

I have a fairly simple list (a number followed by a sentence), here in the right order:
-347 a negative number
-100 another negative number
-25 and again, a negative number
17 some text
25 foo bar
100 two same texts
100 two same texts (almost)
350 a positive number
I need to sort that list each time a new item is added.
I searched S.O. and found that answer :
Sorting in python - how to sort a list containing alphanumeric values?
The code I used is freakish’s, which goes :
import re
def convert(str):
return int("".join(re.findall("\d*", str)))
list1.sort(key=convert)
In order to better explain my problem, I shuffled the list and ran the code.
The result was :
17 some text
-25 and again, a negative number
25 foo bar
100 two same texts (almost)
100 two same texts
-100 another negative number
-347 a negative number
350 a positive number
What went wrong ? What is the precision in the code that would sort naturally the negative numbers?
Sort can accept a tuple, so first sort by the number, then by the text after
list_text = """-347 a negative number
-100 another negative number
-25 and again, a negative number
17 some text
25 foo bar
100 two same texts
100 two same texts (almost)
350 a positive number"""
list1 = list_text.split("\n")
list1.sort(key=lambda x: (int(x.split()[0]), x.split(" ",1)))
print("\n".join(list1))
The easiest approach, IMHO, would be to split the string to individual words, and then sort by the first word converted to an int:
list1.sort(key = lambda x : int(x.split(" ")[0]))
EDIT:
As Keatinge, the above solution won't properly handle two strings that start with the same number. Using the entire string as a secondary search term should solve this issue:
list1.sort(key = lambda x : (int(x.split(" ")[0]), x)

veryfying the output of a string in a certain format

I am trying to check whether or not a licence plate fits a certain format when the user inputs a number plate. It needs to be in the format of two numbers, three letters, and finally two more numbers. If it does not match this format then it must save it to a list.
speed_limit = []
while True :
speed = float()
distance = 50
time=float(raw_input('enter time'))
speed = distance / time
print speed
if speed > 31.2928:
#70 mph converted into meters per second
number_plate = raw_input('enter number plate')
number_plate.upper()
speed_limit.append(number_plate)
print speed_limit
else:
print 'ok'
This is my current code, I am not sure if this is possible or I am asking a too vague question but I need help!
You can do a regular expression match. The regex key that you would be needing is
(\d{2}[A-Z]{3}\d{2})
This returns 2 numbers, 3 letters and 2 numbers. You can try more regex combinations here
Try the following lines in your command prompt to check the code-
import re
m = re.match('(\d{2}[A-Z]{3}\d{2})','12MNB36')
m holds the result if the string matched the pattern or not.

Categories

Resources