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)
Related
#card number
card = input('Number: ')
j = int(card[::2]) # this will jump character by 1
# multiplying each other number by 2
j *= 2
print(j)
So whenever I run this code and input e.g. 1230404
The output would be correct which is 2688
But when I input for example 1230909 the output is 2798, I expected 261818
Let's look at what your code is doing.
You slice every second character from your input string, so '1230909' becomes '1399'.
You convert that to a single int, 1399.
You multiply that number by 2, producing 2798. I assure you that the computer did the math correctly.
It appears what you expected was for each digit to be doubled individually. To do that, you need to convert each digit, double it, and combine them back. Python has great facilities for this, I'd suggest a generator expression inside a join call.
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
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.