About functions - function

In the code below I try to find prime numbers. My problem is that, I am not sure how to use print inside a function.
Is it correct? I get an answer but it both says 6 is not a prime number and it also gives "None". How can I get rid of this "None"? Also, is it okay to use return just like this?
#Prime number
def prime(num):
for i in range (2,num):
if num%i == 0:
print num, "is not a prime number."
return
else:
print num, "is a prime number."
return
print prime(6)

First of all you have print statements in your code already so just calling prime will result in stuff being printed to the screen. When you have a bare return your function will return None. That means that when you do:
print prime(6)
prime(6) will return None which makes this equivalent to:
print None
Then you have a major logic error in your code because you do not check every possible divisor due to returning too early. For example if you have the number be 9, this is not a prime number. However your function will print that it is a prime because on the first run through the for loop i will be 2 which means 9%2 is false so the else branch gets taken and it prints out that the number is prime. The function then returns at that point without checking the rest of the numbers. If you run this code you will see what happens: http://ideone.com/zxdez2
The design issue here is that you really should keep IO separate from the rest of the functionality. Say you wanted to reuse prime somewhere else later on you can't do this without also having that code print out to the screen. This might not be what you want at that later date but it's hard to do something with that. Instead it is much cleaner to return a boolean that represents if the number was prime or not then print out based on that returned value:
def prime(num):
for i in range (2,num):
if num%i == 0:
return False
return True
x = 6
if prime(x):
print x, "is not a prime number."
else:
print x, "is a prime number."

Related

How can a function return if a number is a factor of another?

I'm writing a function for Python 3.7.3 that tests if a number is a factor of another number.
I tried researching on the internet to find some idea about how the write a function that tests the validity of factoring two unknown real numbers. I ended up stumbling upon the difference between factoring and divisibility, which intrigued me somewhat.
def is_factor(f, n):
"""This function returns if f, a real number, is a factor of another
real number n."""
while f * f <= n:
if f % n == 0:
f /= n
#return True?
else: f += 1 #return False?
print(is_factor(1, 15))
The function appears to work, because Python returns None, and that's all. I expect the function to return a True or False solution. There must be some logical error in the code. Any feed back is appreciated.
If you are dealing with integers, use:
def is_factor(f, n):
return n%f==0
If you are dealing with real numbers, the above code works but is very sensitive to floating point imprecision. Instead, you can divide n by f and see if you get back n after rounding to the nearest integer:
def is_factor(f, n, e):
return abs(round(n/f)*f-n)<e

Denary to binary conversion program

How does this denary to binary program work? I am finding it hard to comprehend what is happening behind the code.
Can someone explain the lines 6 onwards?
Number = int(input("Hello. \n\nPlease enter a number to convert: "))
if Number < 0:
print ("Can't be less than 0")
else:
Remainder = 0
String = ""
while Number > 0:
Remainder = Number % 2
Number = Number // 2
String = str(Remainder) + String
print (String)
The idea is to separate out the last part of the binary number, stick it in a buffer, and then remove it from "Number". The method is general and can be used for other bases as well.
Start by looking at it as a dec -> dec "conversion" to understand the principle.
Let's say you have the number 174 (base10). If you want to parse out each individual piece (read as "digit") of it you can calculate the number modulo the base (10), then do an integer division to "remove" that digit from the number. I.e. 174%10 and 174//10 => (Number) 17|4 (Reminder). Next iteration you have 17 from the division and when you perform the same procedure, it'll split it up into 1|7. On the next iteration you'll get 0|1, and after that "Number" will be 0 (which is the exit condition for the loop (while Number > 0)).
In each iteration of the loop you take the remainder (which will be a single digit for the specific base you use (it's a basic property of how bases work)), convert it to a string and concatenate it with the string you had from previous iterations (note the order in the code!), and you'll get the converted number once you've divided your way down to zero.
As mentioned before, this works for any base; you can use base 16 to convert to hex (though you'll need to do some translations for digits above 9), octal (base 8), etc.
Python code for converting denary into binary
denary= int(input('Denary: '))
binary= [0,0,0,0]
while denary>0:
for n,i in enumerate(binary):
if denary//(2**(3-n))>=1:
binary[n]= 1
denary -= 2**(3-n)
print(denary)
print (binary)

How "return" works in Python 2.7 user defined function

The use of the command "return" has always been bothering me since I started learning Python about a month ago(completely no programming background)
The function "double()" seems working fine without me have to reassign the value of the list used as an argument for the function and the value of the elements processed by the function would double as planned. Without the need to assign it outside the function.
However, the function "only_upper()" would require me to assign the list passed as argument through the function in order to see the effect of the function. I have to specify t=only_upper(t) outside of the function to see the effect.
So my question is this: Why are these two seemingly same function produces different result from the use of return?
Please explain in terms as plain as possible due to my inadequate programming skill. Thank you for your input.
def double(x):
for i in range(len(x)):
x[i] = int(x[i])*2
return x
x = [1, 2, 3]
print double(x)
def only_upper(t):
res = []
for s in t:
if s.isupper():
res.append(s)
t = res
return t
t = ['a', 'B', 'C']
t = only_upper(t)
print t
i am assuming that this is your first programming language hence the problem with understanding the return statement found in the functions.
The return in our functions is a means for us to literally return the values we want from that given 'formula' AKA function. For example,
def calculate(x,y):
multiply = x * y
return multiply
print calculate(5,5)
the function calculate defines the steps to be executed in a chunk. Then you ask yourself what values do you want to get from that chunk of steps. In my example, my function is to calculate the multiplied value from 2 values, hence returning the multiplied value. This can be shorten to the following
def calculate(x,y):
return x * y
print calculate(5,5)

stop recursion from 'deepest' reccursion in python 3

I am trying to stop errors happening in my code when an invalid input is entered by the user. Here is a simplified example that demonstrates my problem.
def foo():
try:
a = int(input('1,2,3 or 4'))
except (ValueError, UnboundLocalError):
print ('invalid input')
print ('')
print ('Try 1,2,3 or 4')
foo()
if a == 3:
print ('done')
When I input an intiger the function runs perfectly. When I input a string into the a = int(input()) part it runs foo() again. However, when I then input 3 it prints done' but goes on to give as many ValueError's as times I made an incorrect inputs followed by an UnboundLocalError.I think this is because im running the function over and over inside itself so it then has to 'come out' of this. Is there a better way to re run the function without using recursion? I am new to programming.
Put the last two lines inside the try..except block.
def foo():
try:
a = int(input('1,2,3 or 4'))
if a == 3:
print ('done')
except (ValueError, UnboundLocalError):
print ('invalid input')
print ('')
print ('Try 1,2,3 or 4')
foo()
And you'd better use while loop to avoid increasing the recursion depth:
def foo():
while True:
try:
a = int(input('1,2,3 or 4'))
if a == 3:
print ('done')
break
except (ValueError, UnboundLocalError):
print ('invalid input')
print ('')
print ('Try 1,2,3 or 4')
The issue you're having is that you don't exit the function when you recurse in your exception handler. One solution would be to return foo() when you recurse, but this is still going to be awkward (Python doesn't do tail call optimization, so this will build up a big stack of calls waiting to be returned from, if you keep entering invalid values). A better solution is to use a loop:
a=None:
while a is None:
try:
a = int(input('1,2,3 or 4'))
except ValueError:
print ('invalid input')
print ('')
print ('Try 1,2,3 or 4')
# you could do more validation here, and set `a` back to `None` if it is invalid
if a == 3:
print("done")
The while loop will keep on asking for input until an acceptable value is provided by the user. No recursion is needed.
Pull the try and except block outside of your recursive function This way you don't enter multiple different trys. Then when your recursive function throws an error, it'll go all the way back up it that one any only try block that you have.

random line in file

This question was given to me during an interview. The interview is long over, but I'm still thinking about hte problem and its bugging me:
You have a language that contains the following tools: a rand() function, while and for loops, if statements, and a readline() method (similar to python's readline()). Given these tools, write an algorithm that returns a random line in the file. You don't know the size of the file, and you can only loop over the file's contents once.
I don't know the desired answer, but my solution would be the following:
chosen_line = ""
lines = 0
while (current_line = readline()):
if (rand(0, lines) == 0):
chosen_line = current_line
lines++
return chosen_line
Edit: A good explanation why this works was posted in this comment.
One method, guaranteeing a uniform distribution:
(1) Read the file line-by-line into an array (or similar, e.g. python list)
(2) Use rand() to select a number between 0 and largest index in the array.
Another, not guaranteeing a uniform distribution:
Read each line. On each read, also call rand(). If over a threshold, return the line.
Although similar to Marcin's third option, Luc's implementation always returns the first line, while parsing the whole file.
It should be something like:
chosen_line = ""
treshold = 90
max = 100
while chosen_line == "":
current_line = readline()
if (rand(0, max) > treshold):
chosen_line = current_line
print chosen_line
You could also return current_line in the case no line was chosen and you read the whole file.