I am new to programming in Python and am writing a program to check whether an integer with at most six digits is a palindrome. Here is my code:
def digits(n):
a = (n%10)/1
b = ((n-a)%100)/10
c = ((n-a-10*b)%1000)/100
d = ((n-a-10*b-100*c)%10000)/1000
e = ((n-a-10*b-100*c-1000*d)%100000)/10000
f = ((n-a-10*b-100*c-1000*d-10000*e)%1000000)/100000
n = 123321
digits(n)
def palindrome(n):
if a==f and b==e and c==d:
return True
print("is a palindrome")
else:
return False
print("is not a palindrome")
palindrome(n)
The function digits( ) gives me the first six digits of the number I put in. The palindrome function checks whether the first digit is equal to the sixth, the second to the fifth, and so on. I get the following error message when I try to run the code:
Traceback (most recent call last):
File "<string>", line 20, in <module>
File "<string>", line 13, in palindrome
NameError: name 'a' is not defined
>
It says that the variable 'a' is not defined. I thought 'a' was defined when I ran the digits( ) function. What is going wrong here?
The exception is raised because 'a' is defined in the scope of digits, and not passed to palindrome.
You can return the digits and pass them like seth offered, but in python using every type's best quality is an art.
In your case, accessing with index is done better with string or list rather than integer, so raphael's answer is better in that way.
But even a better solution can be achieved with utilizing the slicing functionality of string, which leads me to the most pythonic solution I can think of:
is_palindrom = lambda number: str(number) == str(number)[::-1]
What it does is looks at the number as a string, looks at it like a string backwards and compares them.
And it works on any number.
The variables a, b, c, d, e, and f are local variables. Make them global variables like so:
def digits(n):
a = (n%10)/1
b = ((n-a)%100)/10
c = ((n-a-10*b)%1000)/100
d = ((n-a-10*b-100*c)%10000)/1000
e = ((n-a-10*b-100*c-1000*d)%100000)/10000
f = ((n-a-10*b-100*c-1000*d-10000*e)%1000000)/100000
return a, b, c, d, e, f
n = 123321
a, b, c, d, e, f = digits(n)
def palindrome(n, a, b, c, d, e, f):
if a==f and b==e and c==d:
return True
print("is a palindrome")
else:
return False
print("is not a palindrome")
palindrome(n, a, b, c, d, e, f)
The reason a isn't defined is that you're just typing it as a variable, when a is only defined inside of the function digits. Furthermore, the function digits does not return anything. Because of that, even if you were to call that function to get the a variable that is hidden inside it, the function would return null.
So, to solve these problems, you will have to replace the a in your palindrome function with digits(n)[a], and you will have to make you digits function return something, preferably a simple list of a through f.
Here I put in my corrections and some other minor things, with comments to show why I did everything.
def digits(n):
a = (n % 10) / 1
b = ((n - a) % 100) / 10
c = ((n - a - 10 * b) % 1000) / 100
d = ((n - a - 10 * b - 100 * c) % 10000) / 1000
e = ((n - a - 10 * b - 100 * c - 1000 * d) % 100000) / 10000
f = ((n - a - 10 * b - 100 * c - 1000 * d - 10000 * e) % 1000000) / 100000
# returns a list of all the variables you created, so you can access them from outside.
return [a, b, c, d, e, f]
# if you call this variable "n" then it can get confusing because all the functions also use "n". the functions will
# therefore "shadow 'n' from outer scope", which is something we want to avoid.
number = 123321
def palindrome(n):
# here we are calling the digits function on "n", and collecting the values from that list we made.
if digits(n)[0] == digits(n)[5] and digits(n)[1] == digits(n)[4] and digits(n)[2] == digits(n)[3]:
# you can't return True before you print, because when you return something the function instantly quits, and
# the print() statement will never be reached.
print("is a palindrome")
return True
else:
print("is not a palindrome")
return False
palindrome(number)
You can convert the number into a string and check if the reverse of the string matches with original string. That will be the easiest way to do it. I understand that you may have to check them using numbers.
Below, I have provided you solutions for both numeric value processing and string processing. Also, this solution does not limit you to six digits.
Numeric processing:
def check_numeric_pal(numval):
temp = numval
ln = len(str(temp))
x = int(ln/2)
for i in range (x):
ln -= 1
a = int(temp/(10**ln))
b = int(temp%10)
if a != b:
print (numval, 'is NOT a Palindrome')
break
temp = int((temp - (a* (10**ln) + b))/10)
ln -= 1
else:
print (numval, 'is a Palindrome')
string processing
def check_palindrome(numval):
if str(numval) == str(numval)[::-1]:
print (numval,'is a Palindrome')
else:
print (numval,'is NOT a Palindrome')
Calling the numeric function:
print ('Processing as numerics values')
check_numeric_pal(12345654321)
check_numeric_pal(12345678901)
check_numeric_pal(123321)
check_numeric_pal(123456)
check_numeric_pal(12321)
check_numeric_pal(12345)
Calling the string function
print ()
print ('Processing as a string')
check_palindrome(12345654321)
check_palindrome(12345678901)
check_palindrome(123321)
check_palindrome(123456)
check_palindrome(12321)
check_palindrome(12345)
The output for these are:
Processing as numerics values
12345654321 is a Palindrome
12345678901 is NOT a Palindrome
123321 is a Palindrome
123456 is NOT a Palindrome
12321 is a Palindrome
12345 is NOT a Palindrome
Processing as a string
12345654321 is a Palindrome
12345678901 is NOT a Palindrome
123321 is a Palindrome
123456 is NOT a Palindrome
12321 is a Palindrome
12345 is NOT a Palindrome
However, if you want to test it using the number pattern, yes, you need to divide and check.
Like Seth and Alani pointed out, you face the problem that a-f are only available within the function.
There are two other points I want to address:
You don't need modulo calculations to get the n'th digit. You can simply cast your number into a string and access the digits by indices.
Your prints won't work because they come after return and are therefore not reachable.
def palindrome(number):
number_str = str(number)
if number_str[0] == number_str[5] and number_str[1] == number_str[4] and number_str[2] == number_str[3]:
return True
else:
return False
n = 123321
if palindrome(n):
print(f"{n} is a palindrome")
else:
print(f"{n} is not a palindrome")
Rearrange 'palindrome' function as put 'digits' function's operations inside it. Also, I suggest you to initialize a,b,c,d,e,f as int variables.
import sympy
equation = input('Enter an equation: ')
a = equation.split(('=') or ('<') or ('>') or ('<=') or ('>=') or ('==') or ('!='))[0:2]
b = sympify(a[0])
c = sympify(a[1])
d = simplify(b - c)
print('This is the equation simplified: ' + str(d))
I want to split the equation in two parts when one of the symbols (=,<,>,>=,<=,==,!=) appear, but in this code it only works when the '=' sign is the symbol.
I think your code should be like that:
import re #<--- add this
import sympy
equation = input('Enter an equation: ')
a = re.split(r'[=|<|>|<=|>=|==]', equation)[0:2] #<--- only change this
b = sympify(a[0])
c = sympify(a[1])
d = simplify(b - c)
print('This is the equation simplified: ' + str(d))
a = input('enter a ')
b = input('enter b ')
c = input('enter c ')
def is_right_angled(a, b, c):
a, b, c = sorted([a, b, c]) #sort inputs smallest to largest
pathag=(a * a + b * b - c * c) #< 0.1 #a ^2 + b ^2 - c ^2 should = 0 approx
if pathag<0.1: # test "pathag" to to see if close
print ("This is a right triangle")
else: # if "pathag" not close, not "right"
print ("This is NOT a right triangle")
return abs(a * a + b * b - c * c) < 0.1
There could be a couple issues specific to the print function not working (I think you might also want to revisit some of the logical assumptions driving your is_right_angled function.)
1) An input function creates a string variable. You will need to explicitly convert this to an int or float variable in order for your function to correctly work with these variables.
a = float(input('enter a '))
2) You are not actually calling the function in the above code. Be sure to call it or the code won't run. Add this to the end of your script:
is_right_angled(a, b, c)
I created a script that should perform simple math juggling by rearranging numbers.
What it should do:
x = 777.0
y = 5
calc = x / y # 155.4
...
Pseudocode:
Rearrange numbers (last digit + first) = 555.
Difference from 777 and 555 = 222
Add 222 to 555 = 777
Basically it should recreate the original variable without doing a real calculation but instead just rearrange numbers and add.
Because of the design of the script i expected it to work only with 4 digit numbers like 333.3. It turns out that it (seems to) work also with numbers like 2543.6452 wich seems to be impossibe at least from my (non academic) view.
Can someone please tell me what happens here? Is the code working correctly or did i create something i simply dont understand? It looks like a illusion to me. :D
x = 5.0
y = 7345.3297
z= y / x
print "Initial Value = " + str(y)
print "Calculate:"
print str(y) + "/" + str(x)
print z # 177.6
print
a = int(str(z)[0])
print "First Number = " + str(a)
print
b = int(str(z)[1])
c = int(str(z)[2])
print "In between = " + str(b) + str(c)
d = int(str(z)[-1]) # treat z as string, take first string after . from z and format it back to int
print "Last Number = " + str(d)
print
print "Rearrange Numbers"
res = str(a+d) +str(b) +str(c)
to_int = int(res)
dif = y - to_int
add = to_int + dif
print "number = " + str(add)
Let's do some substitution here. The bottom lines read:
dif = y - to_int
add = to_int + dif
This can be written in one line as:
add = y - to_int + to_int
or:
add = y
So you do all this "magic" and then completely ignore it to print what you started with. You could put anything above this, all this code does at the end is print y :-)
What causes the problem?
from math import sqrt
print "a : "
a = float(raw_input())
print "b : "
b = float(raw_input())
print "c : "
c = float(raw_input())
d = (a + b + c)/2
s = sqrt(d*(d-a)*(d-b)*(d-c))
print("a+b+c =", a, b, c)
print("Distr. =", d*2, "Area =", s)
Error:
Traceback (most recent call last):
File "C:/Python27/fájlok/háromszög terület2.py", line 11, in <module>
s = sqrt(d*(d-a)*(d-b)*(d-c))
ValueError: math domain error
See also: Why does math.log result in ValueError: math domain error? for the equivalent problem using math.log; Python math domain error using math.acos function for the equivalent problem using math.acos.
The problem is that the Heron's formula holds good only when the sum of the two numbers are greater than the third. You need to check that explicitly.
A better way as you are using a code to do that is by using Exception handling
try:
s = sqrt(d*(d-a)*(d-b)*(d-c))
print "a+b+c =", a, b, c
print "Distr. =", d*2, "Area =", s
except ValueError:
print "Please enter 3 valid sides"
If you want to do it without try block you can do it as
delta = (d*(d-a)*(d-b)*(d-c))
if delta>0:
s = sqrt(delta)
print "a+b+c =", a, b, c
print "Distr. =", d*2, "Area =", s
else:
print "Please enter 3 valid sides"
sqrt gives that error when you try to use it with a negative number. sqrt(-4) gives that error because the result is a complex number.
For that, you need cmath:
>>> from cmath import sqrt
>>> sqrt(-4)
2j
>>> sqrt(4)
(2+0j)
I got the same error with my code until I used cmath instead of math like aneroid said:
import sys
import random
import cmath
x = random.randint(1, 100)
y = random.randint(1, 100)
a = 2 * x * cmath.sqrt(1 - x * 2 - y * 2)
b = 2 * cmath.sqrt(1 - x * 2 - y * 2)
c = 1 - 2 * (x * 2 + y * 2)
print ( 'The point on the sphere is: ', (a, b, c) )
This way ran my code properly.
Use cmath instead..
import cmath
num=cmath.sqrt(your_number)
print(num)
Now regardless of whether the number is negetive or positive you will get a result...