Define a function using a variable? - python

I am trying to define a function that will include a variable n where n will be a string of numbers e.g. "3884892993", the definition of the function starts as is_true(n), however if n is going to be a string should it be is_true(n) and then once the string is defined I can test the function with an example string such as n = "3884892993". I get a syntax error when I use is_true(n) however. And I am just wondering how I would go about testing this function with an example string for n.
My entire function to define is shown here: http://oi44.tinypic.com/282i3qo.jpg but bear in mind I am an absolute novice so there will most probably be many mistakes, but I would appreciate some help from some experts if at all possible :)
def is_valid("n"): #n is the number to be checked.
number =
[int(y) for y in A] #converts the string into a list of useable digits.
altern1 = integer[-2::-2] #sets altern1 as one set of alternating digits.
double = [x*2 for x in altern1] #doubles each element of the list altern1.
sum1 = sum(double) # adds together all the doubled items of the list.
altern2 = integer[-1::-2] #sets altern2 as the other set of alternating digits.
return sum2 = sum(altern2)#sums the other set of alternating digits.
sumtotal = sum1 + sum2 #works out the total sum to be worked with.
for mod = sumtotal % 10: #works out remainder when sumtotal is divided by 10
if mod == 0 : #if remainder is zero sumtotal is a multiple of 10
print 'True' #sumtotal is a multiple of 10 therefore n is a credit card number
else:
print 'False' #sumtotal is NOT a multiple of 10 therefore not a valid credit card number
Here is the actual question:
The algorithm for verifying a number is as follows:
(a) Starting with the penultimate digit, and working towards the rst digit, double each alternating digit.
(b) Sum the doubled digits, treating 13 as 1+3, etc, and add the result to the sum of the undoubled
digits
(c) If the sum is divisible by 10 the number is a valid credit card number.
Write and test a function is_valid() which takes as an argument a credit card number as a string
(eg is valid("49927398716")) and returns True or False depending on whether the number is a
valid credit card number.

Quotes are only used for string literals, you wouldn't enclose a variable or parameter name in quotes to indicate that it will be a string. The function definition would look like:
def is_true(n):
And then in the body of the function you use n to reference the value that is passed in by the caller.
To call the function on a specific value, you do:
is_true("3884892993")
Side suggestion: Think of more explanatory names for your functions and variables. For instance, it seems like your function might be reasonably called is_valid_card_number.

I am not sure what is your question, but if you are trying to:
correctly define the function:
pay attention to the indentation (this is required by Python!),
see here for examples of function definitions,
convert a string variable into integer, you can do this:
new_var = int(old_var)
Generally please pay attention to types, because it is not like in some other dynamically typed languages and strings are not dynamically converted into numbers - you should do it explicitly.
read the value of the variable, based on its name:
my_var = vars().get('variable_name')
(where variable_name is the name of the variable and optionally you can give context within brackets after vars - see help(vars) for details)
Did any of the above solve your problem?
EDIT (based on the clarification):
This should solve your problem:
def is_true(my_variable):
# Here the variable named "my_variable" is accessible
If you want to do something "in-place" on the passed variable, I have a bad news: strings and integers are immutable in Python, thus you are not able to simply change them - you should probably return them as a result of the function (there are at least two workarounds, but I do not recommend them if you are a novice in Python).
EDIT (for proper code styling):
You should probably read PEP 8 to get familiar with what is the coding standard for Python scripts - this is commonly used across Python community and you should follow that (at some point you should appreciate it).

From the Wikipedia article on the Luhn algorithm:
def is_luhn_valid(cc):
num = map(int, str(cc))
return sum(num[::-2] + [sum(divmod(d * 2, 10)) for d in num[-2::-2]]) % 10 == 0

I have no idea what your function is supposed to do, but here are some remarks.
First of all, if you define the function then you use the following syntax
def is_true(n):
# do something
you can call this function like this is_true("3884892993"), i.e. you can pass string as n. Your function now need to treat variable n as a string. So you can use
number = [int(d) for d in n]
which will result in converting string into a list of digits.
One more remark: you used a return statement inside your is_true function. This statement will stop executing the function and return the value. Every code below return will never be executed.

May be like this. I leave your comments
def is_valid(n): #n is the number to be checked.
numbers = [int(y) for y in n] #converts the string into a list of useable digits.
double_alt = [sum([int(i) for i in str(x*2)]) for x in numbers[-2::-2]] #doubles and sum if more than 10each element of the list altern1.
sum1 = sum(double_alt) # adds together all the doubled items of the list.
sum2 = sum(numbers[-1::-2]) #sums the other set of alternating digits.
sumtotal = sum1 + sum2 #works out the total sum to be worked with.
return not sumtotal % 10

Here an implementation of the luhn algorithm that I had to make recently.
def is_valid_luhn(cc):
return not sum([sum(divmod(int(d) * 2, 10)) for d in cc[-2::-2]] + [int(d) for d in cc[-1::-2]]) % 10
# | double | |--- every -2th --| |--- every -1th --|
# |--------- step 1 -----------------|
# |------------- sum doubled digits --------------| |-- sum undoubled digits --|
# |---------------------- step 2: sum doubled/undoubled digits -----------------------|
# |-------------------------- step 3: sum % 10 == 0 --> not sum % 10 --------------------------|
Or if you'd like a more verbose version:
def is_valid_luhn(cc):
total = 0
# Double and sum every 2nd digit starting at -2.
for d in cc[-2::-2]:
# divmod(d*2, 10) returns (d*2 // 10, d*2 % 10)
# sum(divmod) return (d*2 // 10) + (d*2 % 10)
total += sum(divmod(int(d) * 2, 10))
# Sum every 2nd digit starting at -1.
for d in cc[-1::-2]:
total += int(d)
# Check module 10 of total: total % 10 == 0 --> not total % 10
return not total % 10

Related

Creating a function that returns prime numbers under a given maximum?

Instructions are to write a function that returns all prime numbers below a certain max number. The function is_factor was already given, I wrote everything else.
When I run the code I don't get an error message or anything, it's just blank. I'm assuming there's something I'm missing but I don't know what that is.
def is_factor(d, n):
""" True if `d` is a divisor of `n` """
return n % d == 0
def return_primes(max):
result = []
i = 0
while i < max:
if is_factor == True:
return result
i += 1
You should test each i against all divisors smaller than math.sqrt(i). Use the inner loop for that. any collects the results. Don't return result right away, for you should fill it first.
def return_primes(max):
result = []
for i in range(2, max):
if not any(is_factor(j, i) for j in range(2, int(math.sqrt(i)) + 1)):
result.append(i)
return result
print(return_primes(10))
As a side note, use for and range rather than while to make less mistakes and make your code more clear.
The reason that your code is returning blank when you run it, is because you are comparing a function type to the value of True, rather than calling it.
print(is_factor)
<function is_factor at 0x7f8c80275dc0>
In other words, you are doing a comparison between the object itself rather than invoking the function.
Instead, if you wanted to call the function and check the return value from it, you would have to use parenthesis like so:
if(is_factor(a, b) == True):
or even better
if(is_factor(a, b)):
which will inherently check whether or not the function returns True without you needing to specify it.
Additionally, you are not returning anything in your code if the condition does not trigger. I recommend that you include a default return statement at the end of your code, not only within the condition itself.
Now, in terms of the solution to your overall problem and question;
"How can I write a program to calculate the prime numbers below a certain max value?"
To start, a prime number is defined by "any number greater than 1 that has only two factors, 1 and itself."
https://www.splashlearn.com/math-vocabulary/algebra/prime-number
This means that you should not include 1 in the loop, otherwise every single number is divisible by 1 and this can mess up the list you are trying to create.
My recommendation is to start counting from 2 instead, then you can add 1 as a prime number at the end of the function.
Before going over the general answer and algorithm, there are some issues in your code I'd like to address:
It is recommended to use a different name for your variable other than max, because max() is a function in python that is commonly used.
Dividing by 0 is invalid and can break the math within your program. It is a good idea to check the number you are dividing by to ensure it is not zero to make sure you do not run into math issues. Alternatively, if you start your count from 2 upwards, you won't have this issue.
Currently you are not appending anything into your results array, which means no results will be returned.
My recommendation is to add the prime number into the results array once it is found.
Right now, you return the results array as soon as you have calculated the first result. This is a problem because you are trying to capture all of the prime numbers below a specific number, and hence you need more than one result.
You can fix this by returning the results array at the end of the function, not in between, and making sure to append each of the prime numbers as you discover them.
You need to check every single number between 2 and the max number to see if it is prime. Your current code only checks the max number itself and not the numbers in between.
Now I will explain my recommended answer and the algorithm behind it;
def is_factor(d, n):
print("Checking if " + str(n) + " is divisible by " + str(d))
print(n % d == 0)
return n % d == 0
def return_primes(max_num):
result = []
for q in range(2, max_num+1):
count_number_of_trues = 0
for i in range(2, q):
if(i != q):
if(is_factor(i, q)):
print("I " + str(i) + " is a factor of Q " + str(q))
count_number_of_trues += 1
if(q not in result and count_number_of_trues == 0):
result.append(q)
result.append(1)
return sorted(result)
print(return_primes(10))
The central algorithm is that you want to start counting from 2 all the way up to your max number. This is represented by the first loop.
Then, for each of these numbers, you should check every single number from 2 up to that number to see if a divisor exists.
Then, you should count the number of times that the second number is a factor of the first number, and if you get 0 times at the end, then you know it must be a prime number.
Example:
Q=10
"Is I a factor of Q?"
I:
9 - False
8 - False
7 - False
6 - False
5 - True
4 - False
3 - False
2 - True
So for the number 10, we can see that there are 2 factors, 5 and 2 (technically 3 if you include 1, but that is saved for later).
Thus, because 10 has 2 factors [excluding 1] it cannot be prime.
Now let's use 7 as the next example.
Example:
Q=7
"Is I a factor of Q?"
I:
6 - False
5 - False
4 - False
3 - False
2 - False
Notice how every number before 7 all the way down to 2 is NOT a factor, hence 7 is prime.
So all you need to do is loop through every number from 2 to your max number, then within another loop, loop through every number from 2 up to that current number.
Then count the total number of factors, and if the count is equal to 0, then you know the number must be prime.
Some additional recommendations:
although while loops will do the same thing as for loops, for loops are often more convenient to use in python because they initialize the counts for you and can save you some lines of code. Also, for loops will take care of the incrementing process for you so there is no risk of forgetting.
I recommend sorting the list when you return it, it looks nicer that way.
Before adding the prime factor into your results list, check to see if it is already in the list so you don't run into a scenario where multiples of the same number is added (like [2,2,2] for example)
Please note that there are many different ways to implement this, and my example is but one of many possible answers.

An Activity of Binary to Decimal in any base by integrating dictionaries

We have an activity in coding and it seems that my interpretation of this long instruction is not correct. Can you help me with my code by modifying or overhauling it? I am a Highschool student. Thank You.
THE INSTRUCTION:
In Chapter 4, we developed an algorithm for converting from binary to decimal. You can generalize this algorithm to work for a representation in any base. Instead of using a power of 2, you will write a program that converts any base between 2 and 16. Recall that for numbers 10 - 15 we use letters A - F.
In convert.py, define a function named repToDecimal that expects two arguments, a string, and an integer. The second argument should be the base. For example, repToDecimal("10", 8) returns 8, whereas repToDecimal("10", 16) returns 16.
The function should use a lookup table to find the value of any digit. Make sure that this table (it is actually a dictionary) is initialized before the function is defined.
For its keys, use the 10 decimal digits (all strings) and the letters A . . >F (all uppercase). The value stored with each key should be the integer that the digit represents. (The letter A associates with the integer value 10, and so on.)
The main loop of the function should convert each digit to uppercase, look up its value in the table, and use this value in the computation.
A main function that tests the conversion function with numbers in several bases has been provided.
conversionLibrary = {"0":0, "1":1, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "A":10, "B":10, "C":11, "D":13, "E":14, "F":15}
n = input("Enter a number you want changed to base 10: ")
fromBase = int(input("Enter a the base from which you want changed: "))
n = n.upper()
def repToDecimal(n, fromBase):
toNumber = 0
power = 0
for i in range((len(n)),0, -1):
toNumber += conversionLibrary[n[i-1]] * (int(fromBase) ** power)
power += 1
return(toNumber)
def main():
print(repToDecimal('10', 10))
print(repToDecimal('10', 8))
print(repToDecimal('10', 2))
print(repToDecimal('10', 16))
main()
This is my answer. I got 100 points.
dict={'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'A':10,'B':11,'C':12,'D':13,'E':14,'F':15}
def repToDecimal(str,base):
result = 0
#initializing a dictionary
for i in str:
n = dict[i]
result = base * result + n
return result
#calling the method and displaying the result
print(repToDecimal('10',10))
print(repToDecimal('10',8))
print(repToDecimal('10',2))
print(repToDecimal('10',16))

Python recursive function to return the mean of the digits in a number

I'm trying to create a recursive function that returns the average of the digits in a number. For example the average of the number 123 is 2. I know how to write a function that sums the digits but without using for I am no able to return the number to divide the function.
The print value cannot be change so i can't pass a number of digits or something like that.
def media(x):
if x<1:
return 0
else:
return x%10+media(x//10)
print(media(91234))
I assume that it is the mean and not the median as it seems like you've written. To find the mean of the digits, you can convert the number into a type str then extract each digit by iterating over the string with a for ... in string. Next, convert each digit back and find the average of those numbers.
EDIT: It's not recursive, but it doesn't seem meaningful to use recursion for this kind of simple calculation.
Use a for-loop
There is really no reason not to use a for-loop for this.
def media(x):
if x == 0:
return 0
else:
digits = []
while x > 0:
digits.append(x % 10)
x = x // 10
return sum(digits) / len(digits)
If you insist on recursion
You can use additional accumulator parameters to store the sum of digits and the number of digits:
def media(x, sumSoFar=0, nDigitsSoFar=0):
if x == 0 and sumSoFar==0:
return 0
elif x == 0:
return sumSoFar / nDigitsSoFar
else:
return media(x // 10, sumSoFar + (x % 10), nDigitsSoFar + 1)
Please note that python is one of the worst languages for recursion, and in particular it doesn't optimize tail-calls.
Cheating: letting python handle the conversion to string
The builtin function str will convert an integer to a string of digits. You can use this in conjunction with ord to get the value of a digit:
def media(x):
s = str(x)
return sum((ord(c) - ord('0')) for c in s) / len(s)

Lucky Numbers Python Program Incorrect Python Output

Practice Problems /
Lucky String
All submissions to this problem are public. View all submissions.
Lucky numbers are those numbers which contain only "4" and/or "5". For example 4, 5, 44, 54,55,444 are lucky numbers while 457, 987 ,154 are not.
Lucky number sequence is one in which all lucky numbers exist in increasing order for example 4,5,44,45,54,55,444,445,454,455...
Now we concatenate all the lucky numbers (in ascending order) to make a lucky string "4544455455444445454455..."
Given n, your task is to find the nth digit of the lucky string. If the digit is 4 then you >have to print "Hacker" else you have to print "Earth".
Input:
first line contain number of test cases T , next T line contain a single integer n.
Output:
For each test case print Hacker if n-th digit of lucky string is 4 else print Earth if n-th digit of lucky string is 5.
Constraints:
1 <= t <= 10^5
1 <= n <= 10^15
Following is the python code :
test_cases = int(input())
final = []
def check(stra,num):
if stra[num-1]==4:
final.append("Hacker")
else:
final.append("Earth")
def GenStr(num):
stra = "4"
i = int(5)
while(len(stra)<num+2):
X = str(i)
flag = True
for j in range(len(str(i))):
if(X[j]==4 or X[j]==5):
pass
else:
flag = False
if flag==True:
stra+=X
i+=1
print(stra)
return stra
for i in range(test_cases):
num = int(input())
# generate string
stra = GenStr(num)
print("stra "+stra)
# check the stat
check(stra,num)
print("\n".join(final))
What is wrong in this code, please do not mind if it is a silly mistake I am just a beginner in python programming
Comments on your Code
There are several things in your code which don't quite make sense, and need to be addressed:
int(input()) says to ask the user nothing, try to convert any string they type before pressing enter to an integer, and crash otherwise.
The pattern for i in range(len(x)) is almost always wrong in Python. Strings are iterable (they are lists of characters), which is why you can use the list-style index operator (as you do with x[j]), so just iterate over them: for j in str(i).
The pattern if x==True: is always wrong in Python. We prefer if x:.
i = int(5). There is no need to convert an integer literal to an integer. i = 5 is the correct assignment statement.
Try to use better variable names. It's very difficult to follow your code and your reasoning because it is littered with meaningless identifiers like stra (string a??), X, num, etc.
How to Approach the Assignment
I will be honest: I don't fully understand the assignment as presented. It's not clear what a "test case" is or how the input will be formatted (or, for that matter, where the input is coming from). That said, a few thoughts on how to approach this:
Finding numbers that contain only 4 or 5 means treating them as strings. This could be as easy as testing len(str(x).replace('4', '').replace('5', '')), and there are better ways than that.
Listing 'lucky numbers' in increasing order can be accomplished with the built-in sorted function.
Concatenating that list would be ''.join(sorted(lucky_numbers)) or similar.
Taking the nth digit of that list could then be done with string indexing as before.
The immediately incorrect thing is the following. stra is 4. flag always becomes False. Thus stra never grows, and while(len(stra)<num+2): is an infinite loop.
The approach itself will not fully solve the problem, since you can't construct a string of length 1015, it would take too much time and just won't fit into memory.
As #Gassa points out, brute-forcing this is just not going to work; you would need a million gigabytes of RAM, and it would take far too long.
So what would an analytic solution look like?
If you replace "4" with "0" and "5" with "1", you will see that the lucky number sequence becomes 0, 1, 00, 01, 10, 11, 000, 001, 010, 011, 100, 101, 110, 111, .... This should look familiar: it is every 1-digit binary number in ascending order, followed by every 2-digit binary number in ascending order, followed by every 3-digit binary number in ascending order, etc.
So if you do something like
n = 491 # the digit we are seeking (for example)
d = 1 # number of binary digits
p = 2 # 2**d == number of items encoded
while n > d*p: # sought digit is past the end of the next binary expansion?
n -= d*p # reduce offset by appropriate number of digits
d += 1
p *= 2
then n = 233, d = 6 means we are looking for the 233rd character in the 6-bit expansion.
But we can improve on that:
k, n = n // d, n % d
which gives n = 5, k = 38, d = 6 means we are looking at the 5th character of the 38th 6-bit value.
Note: all offsets here are 0-based; if you expect 1-based offsets, you will have to adjust your math accordingly!
The 38th 6-bit value is just 38 converted to a 6-bit binary value; you could muck about with strings to extract the character you want, but it's probably easier to remember that integers are stored as binary internally so we can get what we want with a bit of math:
digit = (k >> (d - n - 1)) & 1 # => 0
so the character in the original string would be a "4".

Add commas into number string [duplicate]

This question already has answers here:
How to print a number using commas as thousands separators
(30 answers)
Closed 10 months ago.
I have a value running through my program that puts out a number rounded to 2 decimal places at the end, like this:
print ("Total cost is: ${:0.2f}".format(TotalAmount))
Is there a way to insert a comma value every 3 digits left of the decimal point?
e.g. 10000.00 becomes 10,000.00 or 1000000.00 becomes 1,000,000.00.
In Python 2.7 and 3.x, you can use the format syntax :,
>>> total_amount = 10000
>>> print("{:,}".format(total_amount))
10,000
>>> print("Total cost is: ${:,.2f}".format(total_amount))
Total cost is: $10,000.00
This is documented in PEP 378 -- Format Specifier for Thousands Separator and has an example in the Official Docs "Using the comma as a thousands separator"
if you are using Python 3 or above, here is an easier way to insert a comma:
First way
value = -12345672
print (format (value, ',d'))
or another way
value = -12345672
print ('{:,}'.format(value))
You could use locale.currency if TotalAmount represents money. It works on Python <2.7 too:
>>> locale.setlocale(locale.LC_ALL, '')
'en_US.utf8'
>>> locale.currency(123456.789, symbol=False, grouping=True)
'123,456.79'
Note: it doesn't work with the C locale so you should set some other locale before calling it.
another way very short is
value = -122212123.12
print(f"{value:,}")
'{:20,.2f}'.format(TotalAmount)
This is not particularly elegant but should work too :
a = "1000000.00"
e = list(a.split(".")[0])
for i in range(len(e))[::-3][1:]:
e.insert(i+1,",")
result = "".join(e)+"."+a.split(".")[1]
A function that works in python2.7+ or python3.1+
def comma(num):
'''Add comma to every 3rd digit. Takes int or float and
returns string.'''
if type(num) == int:
return '{:,}'.format(num)
elif type(num) == float:
return '{:,.2f}'.format(num) # Rounds to 2 decimal places
else:
print("Need int or float as input to function comma()!")
Latest versions of python use f-strings. So you can do this:
print("Total cost: {total_amount:,}
As long as total_amount is a not a string. Otherwise you'd need to cast it to a number type first like so:
print("Total cost: {Decimal(total_amount):,}
The above answers are so much nicer than the code I was using in my (not-homework) project:
def commaize(number):
text = str(number)
parts = text.split(".")
ret = ""
if len(parts) > 1:
ret = "."
ret += parts[1] # Apparently commas aren't used to the right of the decimal point
# The -1 offsets to len() and 0 are because len() is 1 based but text[] is 0 based
for i in range(len(parts[0]) - 1,-1,-1):
# We can't just check (i % 3) because we're counting from right to left
# and i is counting from left to right. We can overcome this by checking
# len() - i, although it needs to be adjusted for the off-by-one with a -1
# We also make sure we aren't at the far-right (len() - 1) so we don't end
# with a comma
if (len(parts[0]) - i - 1) % 3 == 0 and i != len(parts[0]) - 1:
ret = "," + ret
ret = parts[0][i] + ret
return ret
Started learning Python about 5 hours ago, but I think I came up with something for integers (sorry, couldn't figure out floats). I'm in high school, so big chance the code could be way more efficient; I just made something from scratch that made sense to me. If anyone has any ideas on how to improve with ample explanation of how it works, let me know!
# Inserts comma separators
def place_value(num):
perm_num = num # Stores "num" to ensure it cannot be modified
lis_num = list(str(num)) # Makes "num" into a list of single-character strings since lists are easier to manipulate
if len(str(perm_num)) > 3:
index_offset = 0 # Every time a comma is added, the numbers are all shifted over one
for index in range(len(str(perm_num))): # Converts "perm_num" to string so len() can count the length, then uses that for a range
mod_index = (index + 1) % 3 # Locates every 3 index
neg_index = -1 * (index + 1 + index_offset) # Calculates the index that the comma will be inserted at
if mod_index == 0: # If "index" is evenly divisible by 3
lis_num.insert(neg_index, ",") # Adds comma place of negative index
index_offset += 1 # Every time a comma is added, the index of all items in list are increased by 1 from the back
str_num = "".join(lis_num) # Joins list back together into string
else: # If the number is less than or equal to 3 digits long, don't separate with commas
str_num = str(num)
return str_num
I feel comfortable using like this in python:
input_value=float(input())
print("{:,}".format(input_value))

Categories

Resources