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
Related
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)
I am making a game where you crack a code. I want it so it can be any code from 0000 to 9999. I made this script.
from random import *
from time import sleep
pin = [randint(0,9),randint(0,9),randint(0,9),randint(0,9)]
print(pin)
usrinp = int(input(''))
if int(usrinp) == pin:
print('cracked')
the trouble is when I input that code it doesn't work as in nothing comes out as an output. Is there a way to combine these 4 numbers to make a hash or whatever its called?
You have a list of integers, and are comparing it with a single integer. That doesn't work for two reasons:
single integers are never equal to a list, whatever the contents
int() doesn't preserve leading 0 characters; int('0999') returns 999, int('0000') returns 0.
Keep your input and your secret as strings, so you can keep the leading 0. Make them both the same type, so generate a single string, not a list of integers.
Your secret pin can be generated by picking string digits:
digits = '0123456789' # or use from string import digits
pin = ''.join([random.choice(digits) for _ in range(4)]) # 4 random digits, one string
then test the input() value against that pin:
usrinp = input('')
if usrinp == pin:
# ...
Note: you could pick a single random integer too, with random.randint(0, 9999), but that would make it harder for you to then to tell the player if they got some of the digits correct. By generating a string instead, you could, for example, trivially count how many digits they had correct:
if usrinp == pin:
print('Cracked!')
else:
correct_count = 0
for pindigit, userdigit in zip(pin, usrinp):
if pindigit == userdigit:
correct_count += 1
print('Sorry, not the right pin, but you guessed",
correct_count, 'digits correctly!')
You can achieve the same with two integers, but then you'd have to use maths or string conversions to extract each digit and handle values with leading zeros correctly. It all becomes just that little bit more complicated.
Another alternative is to convert the user input to separate integers (so keep your original generated list of integers):
userinp = [int(digit) for digit in input('')]
but unless you also plan to use the digits in arithmetic (summing them, multiplying, etc.) there is no real advantage in that approach over using strings. Both lists and strings are sequences, but generating strings saves you from having to handle users that stubbornly enter 'Your mamma is a <censored>' every time they play your game and break the int() conversions. :-)
None of this requires hashing; hashing is of no use here, because you want to test for equality, not trying to reduce a large amount of potential values to a limited set of options (like trying to put arbitrary values into a table of limited size, or to direct a large number of incoming connections to a limited number of servers that can handle those connections).
It's because you are comparing an integer value with a list.
import random
from time import sleep
pin = 1000*randint(0, 9) + 100*randint(0, 9) + 10*randint(0, 9) + randint(0, 9)
print(pin)
usrinp = int(input(''))
if usrinp == pin:
print('cracked')
this should work, if your pin always is going to be 4 digits, not for the ones with leading zeroes.
To get a four digit int use this:
pin = randint(0, 9999)
So the resulting code would be:
from random import *
from time import sleep
pin = randint(0, 9999)
print('%04d'%pin) # print with leading zeros
usrinp = int(input(''))
if usrinp == pin:
print('cracked')
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
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.
I am trying to make a code that does the following:
Multiplying the digits of an integer and continuing the process gives
the surprising result that the sequence of products always arrives at
a single-digit number.
For example:
715 -> 35 -> 15 -> 5
88 -> 64 -> 24 -> 8
27 -> 14 -> 4
The number of products necessary to reach the single-digit
number is called the persistence number of that integer. Thus 715
and 88 have a persistence number of 3, while 27 has persistence 2.
Make a program to find the only two-digit number with persistence
greater than 3?
I was able to come up with a rough idea and the code is below but it doesn't seem to work:
num2=0
num3=0
num4=0
num=input("what is your number?")
while num in range(10,100):
print 'step1'
num1=num%10*num/10
if num1-10>10:
print 'step2'
num2=num1%10*num1/10
elif num2-num1>10:
print 'step3'
num3=num2%10*num2/10
elif num3-num2>10:
print 'step4'
num4=num3%10*num3/10
elif num4-num3>10:
print 'step5'
print num4
else:
break
The program is Python and I simply can't figure this out. If someone could possibly help me I would appreciate it greatly!
You should use a while or for loop to multiply the digits instead of hardcoding what to do with the first, second and so on digits.
In pseudocode...
productSoFar = 1
digitsLeftToMultipy = #the number
while there are digits left to multiply:
get the next digit and
update produtsSoFar and digitsLeftToMultiply
Also, use
10 <= n < 100
instead of
n in range(10, 100)
So you only do a couple of comparisons instead of a sequential lookup that takes time proportional to the length of the range.
Functions are friends.
Consider a function, getEnds(x), which when passed an integer, x will extract the first digit and the last digit (as integers) and return the result as a tuple in the form (first_digit, last_digit). If x is a single-digit number the tuple will contain one element and be in the form (x), otherwise it will be two. (A simple way to do this is to turn the number into a string, extract the first/last digit as a string, and then convert said strings back into numbers... however, there are many ways: just make sure to honor the function contract, as stated above and -- hopefully -- in the function documentation.)
Then, where n is the current number we are finding the persistence for:
ends = getEnds(n)
while ends contains two elements
n = first element of ends times second element of ends
ends = getEnds(n)
# while terminates when ends contained only one element
# now it's only a matter of "counting" the persistence
For added points, make sure this is in a -- [an] appropriately named/documented -- function as well and consider the use of a recursive function instead of a while-loop.
Happy coding.
If you're trying to get the digits of a number, convert it into a string first and reference them with array notation.