How do I Create a Loop from Raw_Input String Value - python

What I'm trying to do with my program is to ask a user to enter a input string that will later be converted to uppercase or lowercase using str.upper or str.lower.
I have 5 sets options that the user can chose:
a = 'convert to upper case'
b = 'convert to lower case'
c = 'switch case of every alphabetic character to the opposite case'
d = 'convert first and last chrs of each word to upper case, and others to lower'
e = 'no change'
So far I have done the conversion for options a and b. But before I move forward creating a code for options c, d and e. I'm trying to create a loop but I'm not sure how to do it using raw_input and strings.
This is the code that I have so far:
# Conversion Rules
a = 'convert to upper case'
b = 'convert to lower case'
c = 'switch case of every alphabetic character to the opposite case'
d = 'convert first and last chrs of each word to upper case, and others to lower'
e = 'no change'
def upper():
print 'Your Input: %s' % choice
print 'Choosen Conversion Rule: %s' % a
return 'Conversion Result: %s' % option_A
def lower():
print 'Your Input: %s' % choice
print 'Choosen Conversion Rule: %s' % b
return 'Conversion Result: %s' % option_B
choice = str(raw_input('Choose an Option:'))
if (choice == 'A') or (choice == 'a'):
value_A = str(raw_input('Enter a String to Convert:'))
option_A = str.upper(Value_A)
print upper()
elif (choice == 'B') or ('b'):
value_B = str(raw_input('Enter a String to Convert:'))
option_B = str.lower(value_B)
print lower()
else:
print 'Goodbye' # Here I want to break if 'Q' is entered if 'Q' is entered.
So after the user enters an option. For example 'A' or 'a'. The first condition will run but then I want to add a loop that goes back to the beginning of the code and allows the user to enter the option again or choose a different option so a different condition will run.
choice = str(raw_input('Choose an Option:'))
if (choice == 'A') or (choice == 'a'):
value_A = str(raw_input('Enter a String to Convert:'))
option_A = str.upper(Value_A)
print upper()
# I want to add a loop here to go back to the 'choice' variable.

You can put all of your user-interface inside a while loop that loops forever (until for example some key is presses).
# Conversion Rules
a = 'convert to upper case'
b = 'convert to lower case'
c = 'switch case of every alphabetic character to the opposite case'
d = 'convert first and last chrs of each word to upper case, and others to lower'
e = 'no change'
def upper():
print 'Your Input: %s' % choice
print 'Choosen Conversion Rule: %s' % a
return 'Conversion Result: %s' % option_A
def lower():
print 'Your Input: %s' % choice
print 'Choosen Conversion Rule: %s' % b
return 'Conversion Result: %s' % option_B
while True:
choice = str(raw_input('Choose an Option:'))
if (choice == 'A') or (choice == 'a'):
value_A = str(raw_input('Enter a String to Convert:'))
option_A = str.upper(Value_A)
print upper()
elif (choice == 'B') or ('b'):
value_B = str(raw_input('Enter a String to Convert:'))
option_B = str.lower(value_B)
print lower()
else:
print 'Goodbye' # Here I want to break if 'Q' is entered if 'Q' is entered.
break
Note that the "break" is what breaks you out of the loop. Since the user-interface part is in the while loop, it will repeat.

Related

Find And Replace Character In Python

For the get_letter_from_user function, while using the while loop for validation, it keeps repeating the invalid input; I want to make sure that it is a single letter and lower case, and I want to make sure that it doesn't equal the second parameter of the function. I'm not sure what I'm doing wrong, though. (and how to get gud at coding if u have tips)
def get_text_from_user(prompt):
return input(prompt).lower()
def get_letter_from_user(prompt, not_allowed):
not_allowed = ''
allowed = input(prompt).lower()
while not allowed == not_allowed or allowed.isalpha() or len(allowed) > 1:
allowed = str(input('Invalid letter, try again:'))
return allowed
def main():
text = get_text_from_user("Enter some text: ")
ltr1 = get_letter_from_user("Enter a letter: ", '')
ltr2 = get_letter_from_user("Enter another letter: ", ltr1)
new_text = text.replace(ltr1,ltr2)
print("The new text is", new_text)
if __name__ == "__main__":
main()
Suggestion for the function:
def get_letter_from_user(prompt, not_allowed):
allowed = input(prompt).lower()
while allowed == not_allowed or len(allowed) > 1:
print('not_allowed:',not_allowed)
allowed = str(input('Invalid letter, try again:'))
return allowed
ltr1 = get_letter_from_user("Enter a letter: ", '')
ltr2 = get_letter_from_user("Enter another letter: ", ltr1)
Sample output:
Enter a letter: d
Enter another letter: d
not_allowed: d
Invalid letter, try again:d
not_allowed: d
Invalid letter, try again:a
To replace a letter or sequence of letters in a string, you might want to take a look at the string.replace() function:
text = input('Enter some text: ')
find = input('Enter a letter to replace: ')
replace_with = input(f'Enter a letter to replace \'{find}\' with: ')
replaced = text.replace(find, reolace_with)
print('The new text is:', replaced)
To add another little detail because you asked how to get better at coding:
I would never make a function with a parameter that is immediately changed to an empty string. Like:
def get_letter_from_user(prompt, not_allowed):
not_allowed = ''
Rather use a default value like this:
def get_letter_from_user(prompt, not_allowed=''):
...

How can I check if a string has personalized errors?

I'm trying to make a program where I input a name and a surname and the code checks if the name is invalid (list of invalidiations below). If it has any invalidations, it asks me to say the name again and presents me a list of all the invalidations.
Invalidations list (I'll show the code version too):
- The name has digits
- The name has symbols
- The name has no spaces
- It has more then one space
- One of the names is either too short or too long
- The first letter of the name is a space
- The last letter of the name is a space
I can't use exceptions here, because these are not code erros. I've made it with Ifs, but it got to a point where there a simply lots of Ifs for it to be viable.
def has_digits(name):
digits = any(c.isdigit() for c in name)
if digits == True:
return True
print("Your name has digits.")
else:
return False
def has_symbols(name):
symbols = any(not c.isalnum() and not c.isspace() for c in name)
if symbols == True:
return True
print("Your name has symbols.")
else:
return False
def has_no_spaces(name):
spaces = any(c.isspace() for c in name)
if not spaces == True:
return True
print("You only gave me a name.")
else:
return False
def many_spaces(name):
m_s = name.count(' ') > 1
if m_s == True:
return True
print("Your name has more than one space.")
else:
return False
def unrealistic_length(name, surname):
length= (float(len(name)) < 3 or float(len(name)) > 12) or float(len(surname)) < 5 or float(len(surname) > 15)
if length == True:
return True
print("Your name has an unrealistic size.")
else:
return False
def first_space(name):
f_s = name[0] == " "
if f_s == True:
return True
print("The first letter of your name is a space.")
else:
return False
def last_space(name):
l_s = name[-1] == " "
if l_s == True:
return True
print("The last letter of your name is a space.")
else:
return False
name = "bruh browski"
namesplit = name.split(" ")
name1 = namesplit[0]
name2 = namesplit[1]
print(has_digits(name))
print(has_symbols(name))
print(has_no_spaces(name))
print(many_spaces(name))
print(unrealistic_length(name1, name2))
print(first_space(name))
print(last_space(name))
Maybe the prints shouldn't be in the defs themselves. I don't know. I'm almost sure doing a for loop is the way to go, but I just can't imagine how to do it.
Result:
False
False
False
False
False
False
False
The methods you've used to define exactly what counts as each "invalidation" will have to stay, unless you can replace them with something else that does the same thing. But you can check all of those conditions at once using a generator expression:
if any(is_invalid(name) for is_invalid in [
has_digits, has_symbols, has_no_spaces, many_spaces, unrealistic_length, first_name, last_name
]):
# then this string is invalid
# otherwise, all of those returned false, meaning the string is valid.
You can then use that condition to determine when to stop asking the user, or however else you need to.
If you wanted to not individually define all those functions, you could also maybe use lambdas to do the same thing.
As a sidenote, before actually using this in production for checking the validity of names, I advise having a look at the list of Falsehoods Programmers Believe about Names. It's a fun read even if it's not relevant to your use case, though.
You could have a single function which calls all of your other functions and handles it appropriately.
def master_verify(name):
# Put all your verify functions in the list below.
verify_funcs = [has_digits, has_symbols, has_no_spaces, many_spaces,
unrealistic_length, first_space, last_space]
# It will return True if any your functions return True. In this case,
# returning True means the name is invalid (matching your other
# function design). Returning False means the name is valid.
return any(is_invalid(name) for is_invalid in verify_funcs)
Since you mentioned you want the program to find any name errors and ask the user to try again, we can write a loop to handle this.
def get_name():
while True:
# Loop until you get a good name
name = input("Enter your name: ").strip()
if master_verify(name):
# Remember, if True this means invalid
print("Invalid name. Try again.")
continue # continue jumps to the top of a loop, skipping everything else.
return name # Will only get here if the name is valid.
I also suggest you should do the name and surname split inside your unrealistic_length function.
Then, all you need to do is
name = get_name()
# All of the validation has already happened.
print(f"The correct and validated name is: {name}")
Last but not least, anything in a function after a return is unreachable. So a lot of your prints will never happen. Put the print statements before your return.
Alright. I've managed to do it by myself. I still fill there's a better way to do it, but this is the way I found.
errors_list = []
print("Hi. Tell me your first and last name.")
def choose_name(name):
global fname
global sname
fname = ""
sname = ""
global errors_list
try:
no_letters = any(c.isalpha() for c in name)
no_spaces = name.count(" ") == 0
digits = any(c.isdigit() for c in name)
symbols = any(not c.isalnum() and not c.isspace() for c in name)
many_spaces = name.count(" ") > 1
first_space = name[0] == " "
last_space = name[-1] == " "
if no_letters == False:
errors_list.append("It has no letters")
if no_spaces == True:
errors_list.append("It has no spaces")
else:
namesplit = name.split(" ")
fname = namesplit[0]
sname = namesplit[1]
pass
if fname and sname is not "":
bad_length = (float(len(fname)) < 3 or float(len(fname)) > 12) or float(len(sname)) < 4 or float(len(sname) > 15)
if bad_length == True:
errors_list.append("One of your names has an unrealistic size")
pass
else:
bad_length = (float(len(name)) < 3 or float(len(name)) > 12)
if bad_length == True:
errors_list.append("It has an unrealistic size")
pass
if digits == True:
errors_list.append("It has digits")
pass
if symbols == True:
errors_list.append("It has symbols")
pass
if many_spaces == True:
errors_list.append("It has more than one space")
pass
if first_space == True:
errors_list.append("The first letter is a space")
pass
if last_space == True:
errors_list.append("The last letter is a space")
pass
except IndexError:
print("You must write something. Try again.")
name = input("My name is ").title()
choose_name(name)
name = input("My name is ").title()
choose_name(name)
while True:
if len(errors_list) != 0:
print("Your name has these errors:")
for i in errors_list:
print(" " + str(errors_list.index(i) + 1) + "- " + i + ".")
print("Try again.")
errors_list.clear()
name = input("My name is ").title()
choose_name(name)
else:
print("Nice to meet you, " + fname + " " + sname + ".")
break
Result when I type the name '----... '
Hi. Tell me your first and last name.
My name is ----...
Your name has these errors:
1- It has no letters.
2- It has symbols.
3- It has more than one space.
4- The last letter is a space.
Try again.
My name is

how to write an encryption program in python

I am needing a bit of help on my encryption program. Instead of having the program just move the letters by two (c would become a or r would become p) I'd like to be able to have it reference 2 lists, the first one going from a-z normally and the other with letters in different order to act as the encrypt/decrypt side. Hopefully that makes sense. Here's what i have so far.
result = ''
choice = ''
message = ''
while choice != 0:
choice = input("\n Do you want to encrypt or decrypt the message?\n 1 to encrypt, 2 to decrypt or 0 to exit program. ")
if choice == '1':
message = input('\nEnter message for encryption: ')
for i in range(0, len(message)):
result = result + chr(ord(message[i]) - 2)
print(result + '\n\n')
result = ''
if choice == '2':
message = input('\nEnter message to decrypt: ')
for i in range(0, len(message)):
result = result + chr(ord(message[i]) + 2)
print(result + '\n\n')
result = ''
elif choice != '0':
print('You have entered an invalid input, please try again. \n\n')
This works fine and dandy but i'd like to have the lists. Lets say list 1 is A,B,C,D,E and list 2 would be W,N,U,D,P. just for ease of use purposes.
Here is a solution, for small letters only. It can easily be modified to handle also capital letters, by adding them to the text strings.
As can be seen, the space character is at the same position in both lists. This is not necessary, as any character can be translated to any other. However if the decrypted or encrypted is not containing unique characters only, the program will break down.
decrypted = b"abcdefghijklmnopqrstuvwxyz "
encrypted = b"qwertyuiopasdfghjklzxcvbnm "
encrypt_table = bytes.maketrans(decrypted, encrypted)
decrypt_table = bytes.maketrans(encrypted, decrypted)
result = ''
choice = ''
message = ''
while choice != '0':
choice = input("\n Do you want to encrypt or decrypt the message?\n 1 to encrypt, 2 to decrypt or 0 to exit program. ")
if choice == '1':
message = input('\nEnter message for encryption: ')
result = message.translate(encrypt_table)
print(result + '\n\n')
elif choice == '2':
message = input('\nEnter message to decrypt: ')
result = message.translate(decrypt_table)
print(result + '\n\n')
elif choice != '0':
print('You have entered an invalid input, please try again. \n\n')
Ok, so a few things here...
First I'll give you exactly what you were looking for and explain what I used and some of the changes that needed to be made to your original code. Then I'll explain some inherent issues what what you're trying to do and suggest some areas to read up on/some ways you might want to improve what you've got.
Here's the code you're looking for (while retaining the same flow as what you submitted put above):
import random
result = ''
choice = ''
message = ''
characters_in_order = [chr(x) for x in range(32,127)]
while choice != 0:
choice = input("\n Do you want to encrypt or decrypt the message?\n 1 to encrypt, 2 to decrypt or 0 to exit program. ")
if str(choice) == '1':
message = input('\nEnter message for encryption: ')
r_seed = input('Enter an integer to use as a seed: ')
random.seed(r_seed)
shuffled_list = [chr(x) for x in range(32,127)]
random.shuffle(shuffled_list)
for i in range(0, len(message)):
result += shuffled_list[characters_in_order.index(message[i])]
print(result + '\n\n')
result = ''
elif str(choice) == '2':
message = input('\nEnter message to decrypt: ')
r_seed = input('Enter an integer to use as a seed (should be the same one used to encrypt): ')
random.seed(r_seed)
shuffled_list = [chr(x) for x in range(32,127)]
random.shuffle(shuffled_list)
for i in range(0, len(message)):
result += characters_in_order[shuffled_list.index(message[i])]
print(result + '\n\n')
result = ''
elif str(choice) != '0':
print('You have entered an invalid input, please try again. \n\n')
You'll notice that I set a global 'characters in order' list, which is just every ASCII character (32-126) in order. I also imported the 'random' module and used this to shuffle the characters in order according to a seed that the user inputs. As long as this seed is the same on the encryption and decryption end, it will produce the same shuffled list and it should work to encrypt or decipher the same string. Also notice the str() around your input choices. Without that, the user had to input '1', rather than 1 to submit a choice without an error.
All of that said...
Notice that the way the new function works is by looking at a character's index in one list and pulling out the character at that index in another. The method you were using, of incrementing or decrementing a character's ASCII code is basic (though not much more basic than this), but it also has a pretty critical flaw, which is that characters on one end or another of the ASCII set wouldn't return ASCII characters. If you were encrypting it at a bit-level, which would be preferred, this wouldn't matter/would be irrelevant, but here you're not going to get the kind of string back that you want if you were to, for example, enter a [space] (ASCII 32) into your plaintext to be encrypted.
If you're interested, you might want to read up on symmetric key encryption/DES for some ideas on how encryption is really done, though props on the start/interest and this can certainly be a fun way to create some sort of cryptogram puzzle or something along those lines. I won't pretend to be any kind of expert, but I can at least point you in the write direction. (https://en.wikipedia.org/wiki/Data_Encryption_Standard https://en.wikipedia.org/wiki/Symmetric-key_algorithm)
Consider having your code read in a .txt file and print out to a .txt file, rather than using user input for the message.
Again, I'm not an expert by any means and there are definitely some fun uses of the kind of program you're aiming for, just trying to point you in the right direction if this is something that you're interested in. Hope all of that is helpful!
Here is my solution. It uses a randomizer to encrypt the file by assigning a ASCII value to the plain text and randomly shifts it around.
from random import randint
import sys
def menu():
input1=int(input(""" please select what you want to do:
1.Encrypt
2.Decrypt
3.Extended Encryption
4.exit
"""))#menu to choose what you want to do
if input1==1:
encrypt() #takes you to the encrypt function
elif input1==2:
decrypt()#takes you to the decrypt function
elif input1==3:
enxtended()#takes you to the extended encryption function
elif input1==4:
sys.exit #exits the program
else:
print("invalid entry try again")
menu()
def encrypt():
file_name=str(input("please enter the name of the file that you want to open\n"))
try:
text_file=open(file_name + ".txt","r")#puts the text file into read
text_file=text_file.read()#reads the text file
print(text_file)#prints the strings in the document
except:
print("error try again")
encrypt()
random(text_file)
def random(text_file):
list1=("")#creates blank string
for x in range (0,8):
num=(randint(33,126))#generates a random number between33 and 126
ascii1=chr(num) #converts it into an ascii character
list1=list1+ascii1#adds the ascii character to the blank string list1
print (f"your 8 key code is {list1}") #prints 8 character code
offset(list1,text_file)
def offset(list1,text_file):
total=0
for x in range (8,):
total=total+ord(list1[x]) #turns each character into an ascii value
total=total/8 #divides it by
total=round(total,0)#rounds it to 0 decimel places
print(total)
total=total-32#minuses 32 from total
print(f"your offset factor is {total}")
encrypting(total,text_file)
def encrypting(total,text_file):
length=len(text_file)
string1=("")
for x in range (length,):
numascii=ord(text_file[x])#turns the characters into its ascii value
numascii=int(numascii)#makes sure they are integers
if numascii==32:
letter=chr(32)#converts spaces back into spaces
string1=string1+letter#adds space to thestring
else:
numascii1=numascii+total#adds the character value to the offset factor
numascii1=int(numascii1)#makes sure it is an integer
if numascii1>126:# if the ascii value is great then 126
numascii1=numascii1-94#minus 94 from it
letter=chr(numascii1)#turn it into a character
string1=string1+letter#add it to the string
else:
letter=chr(numascii1)#turn the ascii value into a character
string1=string1+letter#add it to the string
print(f"your encrypted file is {string1}")
savefile(string1)
menu()
I have written separate programs for encryption and decryption. Both of these use file manipulation techniques. Use the username 'eggs' and password 'chicks' so that not anyone can see my secret code. I have used hashlib for more security. Just change the User 'Soumajit' to your respective Username to make it work. The first one is encryption and the next one is for decryption.
#ENCRYPTION
from time import sleep
import subprocess
import hashlib
def copy2clip(txt):
cmd='echo '+txt.strip()+'|clip'
return subprocess.check_call(cmd, shell=True)
def en():
alphabet = "abcdefghijklmnopqsrtuwvxyzABCDEFGHIJKLMNOPQSRTUVWXYZ,./?:;!##$%_&* ()`-+=1234567890"
encrypt = ""
decrypt = ""
print
print "Type y for yes and anything else for no"
start = raw_input("Do you want to import file from desktop? ")
if start == "y":
Open = raw_input("Enter the .txt file you want to open in desktop: ")
a = open("C://Users//Soumajit//Desktop//" + Open + ".txt", "r")
print
x = (a.read())
copy2clip(x)
a.close()
print "Right click and select paste below to encrypt"
print
message = raw_input()
for i in message:
x = alphabet.find(i)
new = (x - 5) % 74
encrypt += alphabet[new]
e2 = encrypt[::-1]
else:
print "Type your message below"
message = raw_input("")
for i in message:
x = alphabet.find(i)
new = (x - 5) % 74
encrypt += alphabet[new]
e2 = encrypt[::-1]
print
a = raw_input("By what name do you want to save it?: ")
file = open(a + ".txt", 'wb')
file.write(e2)
file.close()
copy = raw_input("Do you want to copy your file? ")
if copy == 'y':
copy2clip(e2)
print 'Your encrypted file has been copied to the clipboard'
else:
print "Your encrypted file has been saved with the name " + str(a) + " in desktop"
print "To decrypt it, use my other program"
sleep(3)
u = 'e415bf03b4d860dccba57cea46371f831d772ba1deca47f28fa7d1f7'
p = 'c35f7f79dc34a678beb2b4106c84c9963561e7c64bc170e50c429b9a'
ur = raw_input('Enter your username: ')
ur1 = hashlib.sha224(ur).hexdigest()
pr = raw_input('Enter your password: ')
pr1 = hashlib.sha224(pr).hexdigest()
if ur1 == u and pr1 == p:
print 'Access granted'
sleep(1)
en()
else:
print "Incorrect username or password"
sleep(1)
#DECRYPTION
from time import sleep
import subprocess
import hashlib
def copy2clip(txt):
cmd='echo '+txt.strip()+'|clip'
return subprocess.check_call(cmd, shell=True)
def de():
print "Type y for yes and anything else for no"
start = raw_input("Do you want to import file from desktop? ")
if start == "y":
Open = raw_input("Enter the .txt file you want to open from folder: ")
a = open("C://Users//Soumajit//Desktop//" + Open + ".txt", "r")
x = (a.read())
#print x
copy2clip(x)
print "Right click and select paste below to decrypt"
print
message = raw_input()
a.close()
alphabet = "abcdefghijklmnopqsrtuwvxyzABCDEFGHIJKLMNOPQSRTUVWXYZ,./?:;!##$%_&*()`-+=1234567890"
decrypt = ''
for i in message:
x = alphabet.find(i)
new = (x + 5) % 74
decrypt += alphabet[new]
d2 = decrypt[::-1]
d3 = d2.replace("`", " ")
final = d3.replace("2", " ")
print
print final
else:
print "Type or paste your encrypted text below"
print
message = raw_input()
alphabet = "abcdefghijklmnopqsrtuwvxyzABCDEFGHIJKLMNOPQSRTUVWXYZ,./?:;!##$%_&*()`-+=1234567890"
decrypt = ''
for i in message:
x = alphabet.find(i)
new = (x + 5) % 74
decrypt += alphabet[new]
d2 = decrypt[::-1]
d3 = d2.replace("`", " ")
final = d3.replace("2", " ")
print
print final
u = 'e415bf03b4d860dccba57cea46371f831d772ba1deca47f28fa7d1f7'
p = 'c35f7f79dc34a678beb2b4106c84c9963561e7c64bc170e50c429b9a'
ur = raw_input('Enter your username: ')
ur1 = hashlib.sha224(ur).hexdigest()
pr = raw_input('Enter your password: ')
pr1 = hashlib.sha224(pr).hexdigest()
if ur1 == u and pr1 == p:
print 'Access granted'
sleep(1)
de()
print
end = raw_input('press q to quit: ')
while end != 'q':
print 'You did not type q'
end = raw_input('press q to quit: ')
if end == 'q':
quit()
else:
print 'Incorrect username or password'
sleep(1)
quit()

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