How to prevent printing from previous function in current function? - python

I'm currently writing a test function for class to test provided cases on provided solution code. However I'm running into an issue where a print statement is executing when I don't want it to.
This is the provided solution that I'm testing:
def alphapinDecode(tone):
phone_num = ''
if checkTone(tone): #or checkTone2
while len(tone) > 0:
# retrieve the first tone
next_tone = tone[0:2]
tone = tone[2:]
# find its position
cons = next_tone[0]
vow = next_tone[1]
num1 = consonants.find(cons)
num2 = vowels.find(vow)
# reconstruct this part of the number -
# multiply (was divided) and add back
# the remainder from the encryption division.
phone = (num1 * 5) + num2
# recreate the number
# by treating it as a string
phone = str(phone)
# if single digit, not leading digit, add 0
if len(phone) == 1 and phone_num != '':
phone = '0' + phone
phone_num = phone_num + phone
# but return in original format
phone_num = int(phone_num)
else:
print('Tone is not in correct format.')
phone_num = -1
return phone_num
Here's the (partially done) code for the test function I have written:
def test_decode(f):
testCases = (
('lo', 43),
('hi', 27),
('bomelela', 3464140),
('bomeluco', 3464408),
('', -1),
('abcd', -1),
('diju', 1234),
)
for i in range(len(testCases)):
if f(testCases[i][0]) == testCases[i][1] and testCases[i][1] == -1:
print('Checking '+ f.__name__ + '(' + testCases[i][0] + ')...Tone is not in correct format.')
print('Its value -1 is correct!')
return None
When executing test_decode(alphapinDecode), I get this:
Tone is not in correct format.
Checking alphapinDecode()...Tone is not in correct format.
Its value -1 is correct!
Tone is not in correct format.
Checking alphapinDecode(abcd)...Tone is not in correct format.
Its value -1 is correct!
As you can see, because of the print statement in alphapinDecode(I think), it is printing an extra "Tone is not in correct format." above the print statement I have written.
How would I prevent this print statement from executing, and why is it printing if the print statement I wrote in my test function doesn't ask for the result of alphapinDecode?
We are not allowed to alter the code of the given solution.
I'm fairly new to stackOverflow, so sorry for any formatting issues. Thank you!
Edit: Fixed the idents of the test_decode function

One easy solution would be to pass an extra parameter say, a boolean variable debug to the function. That would go something like this.
def func1(var1, debug):
if debug:
print("Printing from func1")
# Do additional stuff
Now when you call it. You now have the option of setting the debug variable.
func1("hello", debug=True) # will print the statement
func1("hello", debug=False) # will not print statement.
If you cannot modify the called function. Then you can follow this method. explained by #FakeRainBrigand here.
import sys, os
# Disable
def blockPrint():
sys.stdout = open(os.devnull, 'w')
# Restore
def enablePrint():
sys.stdout = sys.__stdout__
print 'This will print'
blockPrint()
print "This won't"
enablePrint()
print "This will too"

Related

my decrypting program is doing the wrong thing

Today I made a .py file that decrypts strings encrypted with a vigenere square. I have gotten this far but I cant seem to add spaces to the ciphr list and encr_txt because it garbles the decrypted message. Instead of "message is, hello my name is slim shady", you get "message is, hellprvmwhwebwrw k d thady", where as if i leave spaces out of encr_txt and the ciphr list I get a fine message. I do not know how to fix this there are no errors either, I just started coding in python a couple days ago so if its obvious i'm sorry. Also I know this could be done way easier but im learning lists so i chose to make it this way instead of something like this:
Another question i found relating my problem but does not describe my situation
Code :
# -*- coding: utf-8 -*-
# ^ encoding
# Encrypted text
# encr_txt = 'tkedobaxoudqrrffhhhalbmmcnedeo'
encr_txt = 'qexpg vy zeen ie wdrm elsmy'
#encr_list = list(encr_txt)
txtpos = 0
# Key to ^
key = 'james'
keypos = 0
limit = len(encr_txt)
limitpos = 0
# Vigenere square
ciphr = ['abcdefghijklmnopqrstuvwxyz ',
'bcdefghijklmnopqrstuvwxyz a',
'cdefghijklmnopqrstuvwxyz ab',
'defghijklmnopqrstuvwxyz abc',
'efghijklmnopqrstuvwxyz abcd',
'fghijklmnopqrstuvwxyz abcde',
'ghijklmnopqrstuvwxyz abcdef',
'hijklmnopqrstuvwxyz abcdefg',
'ijklmnopqrstuvwxyz abcdefgh',
'jklmnopqrstuvwxyz abcdefghi',
'klmnopqrstuvwxyz abcdefghij',
'lmnopqrstuvwxyz abcdefghijk',
'mnopqrstuvwxyz abcdefghijkl',
'nopqrstuvwxyz abcdefghijklm',
'opqrstuvwxyz abcdefghijklmn',
'pqrstuvwxyz abcdefghijklmno',
'qrstuvwxyz abcdefghijklmnop',
'rstuvwxyz abcdefghijklmnopq',
'stuvwxyz abcdefghijklmnopqr',
'tuvwxyz abcdefghijklmnopqrs',
'uvwxyz abcdefghijklmnopqrst',
'vwxyz abcdefghijklmnopqrstu',
'wxyz abcdefghijklmnopqrtsuv',
'xyz abcdefghijklmnopqrtsuvw',
'yz abcdefghijklmnopqrtsuvwx',
'z abcdefghijklmnopqrtsuvwxy',
'abcdefghijklmnopqrtsuvwxyz ']
first = ciphr[0]
string = ''
def start():
global limitpos
limitpos += 1
global keypos
for i in ciphr:
if keypos == len(key):
keypos = 0
else:
pass
if i[0] == key[keypos]:
#print "%s, %s" % (i[0], i)
global currenti
currenti = i
#print currenti
finder()
break
else:
pass
def finder():
global keypos
global txtpos
done = False
position = 0
while done == False:
for i in currenti[position]:
if i == '_':
pass
if i == encr_txt[txtpos]:
global string
string = string + first[position]
#print "message is, %s" % string
keypos += 1
txtpos += 1
done = True
if limitpos == limit:
print "message is, %s" % string
break
else:
start()
else:
position += 1
pass
start()
Adding spaces to the table changes the way the cipher works. You can't expect to make that kind of change and not affect the way messages are encrypted and decrypted!
As an aside, the last row of your table is incorrect. It's identical to the first row, but it should have the space in the first position.

How to run one function and then another function within the main()

So I am just learning Python and am working on an online exercises to get use to the language and software itself. Right now I am working on making one function (getData()) run and then the results from that function to run into another function (getStats()) that is all with a main(). Each one works individually but I am having a problem with the main(). I can get my first getData() to run and make my list but I can't get that list to run directly into getStats(). It actually runs the getData() again and then comes back with an error message when I put in an input . Does anyone have any suggestions for me to not get that error message and then to actually run my getStats()?
def getData():
import math
pop = []
while True:
user = raw_input("Please enter a population number (-1 to quit): ")
pop.append(user)
if user == '-1':
break
if user <= '0':
print "Population not valid, please input a value higher then 0"
new_pop = map(int, pop)
pop2 = filter(lambda x:x >=1, new_pop)
print "Your population list is: ", pop2
return
def getStats():
i = ""
asc = sorted(i)
print "The collected data in the asecending order", asc
dec = sorted(i, reverse = True)
print "The collected data in the descending order", dec
maxi = max(i)
print "The maximum of the collected data is", maxi
mini = min(i)
print "The minimum of the collected data is",mini
def getMean(i):
aver = round(sum(i), 2)/round(len(i), 2)
print "The average of the collected data is %.2f" % aver
getMean(i)
def getStdev(i):
aver = sum(i)/len(i)
var = sum(pow(user-aver,2) for user in i)/len(i)
stdev = math.sqrt(var)
print "The standard deviation of the collected data is %.2f" % stdev
return
def main():
getData()
getStats(getData())
main()
The variables inside each function cannot be accessed by other functions variable/function scope.
One way to use them is to have the function return those values. Here is a simplified example:
def get_data():
data = raw_input('Ask for data')
return data
def get_stats(data):
sorted_data = sorted(data)
print 'Sorted:', sorted_data
data = get_data() # get_data will point 'data' to the value returned
get_stats(data) # call get_stats, and pass 'data' as an argument
Some other thoughts:
You don't really need the main() function. It's not doing anything.
What is more common, is adding a conditional statement to only run this if you are running the file itself, but not when it's imported as a module:
if __name__ == '__main__':
data = get_data()
get_stats(data)
Check out PEP 008
Usually your imports should be at the beginning of the file (Imports)
Function names are camel_case

variable type change from global variable to method variable why?

I initate a variable globally then when I go to change the variable it's type goes from dictionary (good) to string ( bad) and I am kinda sure why but not really. I am not 100% on python scoping.
The code in full is below please notice I have alot of print statements which I was using as testing. I am including all the code to the point of the issue to give you all a full grasp of what I am trying to do.
totalEntries = 0
print 'this is first ' + str((type(totalEntries))) #prints type int (good)
perPage = 0
currentPage = 1
Pcity = ''
api_data = ''
is_last_page = False
apiCallNum = 1
tableDefined = False
def getApiData(city):
global Pcity
global apiCallNum
global apiEndpoint
Pcity = city
apiEndpoint = #just a link ignore this
api_data = requests.get(apiEndpoint).json()
print(api_data)
print('your testing this' + str(type(api_data))) #prints dict (good)
print ("Current API Call " + str(apiCallNum))
apiCallNum += 1
print('your testing this' + str(type(api_data))) #prints dict (good)
def populateVars():
global totalEntries
print "this is second " + str(type(totalEntries)) #prints int (good)
print('your testing this' + str(type(api_data))) #prints string (bad)
totalEntries = api_data['total_entries']
thank you all
Assignments made to api_data inside getApiData won't be visible anywhere else because you didn't mark it as global.
Add global api_data to the beginning of getApiData.
Incidentally, you only need the global statement if you want to assign to a global variable - you can access their values just fine without the statement. So strictly speaking you don't need global apiEndpoint.

python input check function not being called properly

I'm working on a very simple temperature converter in Python (just for practice), and am struggling with some of the UX components. I'd like to have checks in place to continue prompting for variable input when invalid entries are made. My full code is below:
o_temp = ''
def temp_input(o_temp):
o_temp = raw_input('Enter a temperature (round to nearest integer): ')
return o_temp
def temp_input_check(o_temp):
o_temp = list(o_temp)
for i in o_temp:
if i not in '1234567890':
print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
temp_input(o_temp)
else:
break
def converter(o_temp):
unit = raw_input('Convert to (F)ahrenheit or (C)elsius? ')
unit = unit.upper()
if unit == 'F' or unit == 'f':
n_temp = (9.0/5.0) * int(o_temp) + 32
print '%d C = %d F' % (o_temp, n_temp)
quit()
elif unit == 'C' or unit == 'c':
n_temp = (5.0/9.0) * (int(o_temp) - 32)
print '%d F = %d C' % (o_temp, n_temp)
quit()
else: #check for valid entry
print 'Invalid entry. Please enter F for Fahrenheit or C for Celsius'
unit_input()
def temp_converter():
#title, call sub-functions
print ''
print 'Temperature Converter'
print ''
temp_input(o_temp)
temp_input_check(o_temp)
converter(o_temp)
temp_converter()
However, when I enter an invalid entry (say, a letter or a combination of letters and numbers) into the o_temp prompt, the code does not seem to recognize that this is invalid and continues with the unit prompt. Am I not correctly returning the variable? What's the issue here? I tried removing the initial o_temp declaration but then I got "NameError: global name 'o_temp' is not defined"
EDIT
I came up with this solution, any further suggestions to refine the code at all?
def converter():
print 'Temperature Converter'
while 1:
temp = raw_input('Starting temperature? ')
try:
temp = float(temp)
except ValueError:
print 'Invalid entry. Please enter only the numerical temperature measurement.'
else:
break
while 1:
unit = raw_input('Convert to Fahrenheit or Celsius? ')
if unit.upper().startswith('F') == True:
print "%f C = %f F" % (temp, temp*9./5+32)
return False
elif unit.upper().startswith('C') == True:
print "%f F = %f C" % (temp, (temp-32)*5./9)
return False
else:
print 'Invalid entry. Please enter F for Fahrenheit or C for Celsius'
converter()
You define some functions, then call temp_coverter(). This function calls temp_input(otemp), sending it an empty string for no reason that I can see, other than the possibility that you're unaware that you can define a function with no parameters. This function then returns a value, which you don't save.
After that, temp_input_check(otemp) is called, which attempts to validate the same empty string. This function's returned value isn't saved, which isn't a big loss, because None isn't a particularly useful value to save.
Then converter(otemp) sends the same old empty string to the actual converter. Mayhem results.
I recommend spending some quality time with the tutorial.
When you're done, the code should look more like this:
def converter():
print 'Temperature Converter'
unit = raw_input('Convert to Fahrenheit or Celsius? ')
while 1:
temp = raw_input('Starting temperature? ')
try:
temp = float(temp)
except ValueError:
print 'Not a valid temperature.'
else:
break
if unit.lower().startswith('f'):
print "%f C = %f F" % (temp, temp*9./5+32)
else:
print "%f F = %f C" % (temp, (temp-32)*5./9)
converter()
Your for loop isn't implemented correctly.
def temp_input_check(o_temp):
o_temp = list(o_temp)
for i in o_temp:
if i not in '1234567890':
print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
temp_input(o_temp)
else:
break
You check every character for an invalid entry. If you typed in multiple invalid characters, it'll keep hitting the trigger after you have already determined that the string is invalid!
Also, if your first character is valid, you're telling it to break from the for loop (in your code 1fdsdfdsf would be a valid temperature, because it would skip every character after hitting that else statement and breakout from the loop).
Also, your temp_input doesn't need to accept an argument in the function (you're just gonna return the user's input). You actually want to assign it after you call the function instead of having it as an argument
Also, you're calling temp_input again to get the user input, but not capturing that anywhere with a return - so it's ultimately not doing anything. You should have your function return a True or False, and then catch that on the outside of the checker if you want to have the user try and enter a better temperature:
def temp_input_check(o_temp):
o_temp = list(o_temp)
for i in o_temp:
if i not in '1234567890':
print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
return False
else:
pass # nothing is wrong with this character, keep checking
return True # if we hit this line, there were no problem characters
Then, when you call the stuff:
while(1):
o_temp = temp_input()
if temp_input_check(o_temp):
break # this means our o_temp is allllright.
# otherwise, go back to the start of the loop and ask for another temp
converter(o_temp)
because you mentioned 'o_temp' as the function parameter in the end but mentioned it as a empty string at Start. Don't give same names for global & function variables (just to avoid confusion). the function took the o_temp you mentioned above as parameter and neglects the one inside them.
Also the raw_input won't consider the input as string. Try input instead to avoid the sensibility of not using str to correct the loop.
This will do:
def converter():
o_temp = float(raw_input('Enter a temperature (round to nearest integer): '))
for i in str(o_temp):
if i not in ['1','2','3','4','5','6','7','8','9','0','.']:
print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
unit = raw_input('Convert to (F)ahrenheit or (C)elsius? ')
if unit in ['f','F']:
n_temp = (9.0/5.0) * float(o_temp) + 32
print '%f C = %f F' % (o_temp, n_temp)
elif unit in ['c','C']:
n_temp = (5.0/9.0) * (float(o_temp) - 32)
print '%f F = %f C' % (o_temp, n_temp)
else: #check for valid entry
print 'Invalid entry. Please enter F for Fahrenheit or C for Celsius'
unit_input()
def temp_converter():
#title, call sub-functions
print ''
print 'Temperature Converter'
print ''
converter()
print temp_converter()

Problems transferring information from one part of a function to another

While working on my program I have run into a problem where the information stored in Menu option 1 is not being transferred to Menu option 2. As you can see it is correctly stored when in menu one. When it returns to go to menu option 2 its like it never went to option 1.
update #1:
some suggestions I've had is to understand scope? from what I can tell the program is not passing the data along to its parent program even though I've typed out return in each of the definitions.
#Must be able to store at least 4 grades
#Each class can have up to 6 tests and 8 hw's
#Weighted 40%*testavg 40% hw average attendance is 20%
#User must be able to input a minimum grade warning
#after each test the your program must calculate the students average and issue warning if necessary
##Define the Modules##
import math
def menu (a): #2nd thing to happen
menuend = 'a'
while menuend not in 'e':
menuend = raw_input("Type anything other then 'e' to continue:\n")
print "What would you like to do ?"
menudo = 0
print "1 - Enter Courses\n2 - Select Course to Edit\n3 - Save File\n4 - Load File\n5 - Exit\n"
menudo = input("Enter Selection:")
if (menudo == 1):
menuchck = 0
menuchck = raw_input("\nYou have entered #1 (y/n)?:\n")
if menuchck in ["Yes","yes","y","Y"]:
x = m1()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 2):
menuchck1 = 0
menuchck1 = raw_input("\nYou have entered #2 (y/n)?:\n")
if menuchck1 in ["Yes","yes","y","Y"]:
x = m2()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 3):
print "Entered 3"
elif (menudo == 4):
print "Entered 4"
else:
print "Anything Else Entered"
def course(): #3rd thing to happen
b = {}
while True:
while True:
print "\n",name,", please enter your courses below ('e' to end):"
coursename = raw_input("Course Name:")
if (coursename == 'e'):
break
will = None
while will not in ('y','n'):
will = raw_input('Ok for this name : %s ? (y/n)' % coursename)
if will=='y':
b[coursename] = {}
print "\n",name,", current course load:\n",b
coursechck = None
while coursechck not in ('y','n'):
coursechck = raw_input("Are your courses correct (y/n)")
if coursechck =='y':
return b
else:
b = {}
print
##Menu Options##
def m1():
a = course()
return a
def m2():
print "Excellent",name,"lets see what courses your enrolled in\n"
print x
return x
###User Input Section###
name = raw_input("Enter Students Name:\n")
a = {}
menu(a)
raw_input("This is the end, my only friend the end")
In your if-elif blocks in the do==1 case, you write m1(), but for the last case, you write x=m1(). You should have the latter everywhere (by typing m1() you only run the function, but do not store the returned x anywhere).
By the way, you can avoid this if-elif confusion using if chck in ["Yes","yes","Y","y"]:

Categories