How can I fix a for loop that checks dictionary values? - regex

I know it may sound like a newbie question, but i'm having a hard time trying to make a loop work.
I'm using Julia language to create a simple regular expressions that checks if a telephone number is valid and return the estate of the number according to the code area. Here are the details:
1-User enters the phone number;
2-Regex tests if it's a valid number;
3-The area code is parsed and checked if present in the dictionary values. If yes, then it should return the key owning that value. Otherwise a simple message saying that area code doesn't exist should be printed.
The problem is: the loop goes for as long as possible, printing if the value is available or not everytime it checks for it in the dictionary. A break wouldn't help much: as soon as it got the first check, it would simply stop.
Then ofc I noticed I had to take the final print statement out of the loop and even maybe assign a variable to get the value copied, but it still overwrites with the very last "Number doesn't exist" result.
How can I rewrite this code so it works?
regexTel = r"^(\+55)?[\s]?\(?(\d{2})?\)?[\s-]?(9?\d{4}[\s-]?\d{4})$"
areaCode = Dict("City A"=> [68],
"City B"=> [82], [...] (and so on)
print("Type the phone number:\n")
telNum = readline()
validTel = (match(regexTel, telNum))
fnlAreaCd = parse(Int32, validTel[2])
for (cityCode, availbCode) in areaCode
if fnlAreaCd in availbCode
println("Phone number: ", validTel[3], "\n",
"Area code: ", fnlAreaCd, "\n",
"City: ", cityCode)
else
println("Area code doesn't exist")
end
end

Your usage of Dict seems strange to me. I think you should use it the other way around.
I believe that the area codes are unique, then the varaible areaCode would be like this:
areaCode = Dict(68 => "City A", 82 => "City B", ...) # do you need to wrap them in an array?
It'll allow you to write much simplier code:
if haskey(areaCode, fnlAreaCd)
cityCode = areaCode[fnlAreaCd]
println("Phone number: ", validTel[3], "\n",
"Area code: ", fnlAreaCd, "\n",
"City: ", cityCode)
else
println("Area code doesn't exist")
end

The matching city won't necessarily be the first entry in the dictionary, but you have instructed the code to say it doesn't exist any time it finds a non-match! Try this instead of your bare loop:
function lookup_areacode(acode)
code_exists = false
for (cityCode, availbCode) in areaCode
if acode in availbCode
code_exists = true
println("Phone number: ", tel, "\n",
"Area code: ", acode, "\n",
"City: ", cityCode)
end
end
if !code_exists
println("Area code doesn't exist")
end
end
lookup_areacode(fnlAreaCd)
You may want to move the dictionary inside the function for neatness.

Related

Chatbot problem - infinite recursion - Codecademy question

I'm learning how to code using Codecademy and I am really stuck on a question, and would love to be pointed in the right direction!
The code for the most part works, I just cannot get it to respond to the .match_reply function correctly. The idea is that the chatbot should identify the regex in self.alienbabble and respond with the appropriate answer. However, it is bugging out with an infinite recursion of all the responses of that function.
# importing regex and random libraries
import re
import random
class AlienBot:
# potential negative responses
negative_responses = ("no", "nope", "nah", "naw", "not a chance", "sorry")
# keywords for exiting the conversation
exit_commands = ("quit", "pause", "exit", "goodbye", "bye", "later")
# random starter questions
random_questions = (
"Why are you here? ",
"Are there many humans like you? ",
"What do you consume for sustenance? ",
"Is there intelligent life on this planet? ",
"Does Earth have a leader? ",
"What planets have you visited? ",
"What technology do you have on this planet? "
)
def __init__(self):
self.alienbabble = {'describe_planet_intent': '.*\s*your planet.*','answer_why_intent': 'why\sare.*', 'cubed_intent': '.*cube.*(\d+)'}
# Define .greet() below:
def greet(self):
self.name = input("Hello. What is your name?")
will_help = input(f"Hi {self.name}, I'm Etcetera. I'm not from this planet. Will you help me learn about your planet? ")
if will_help in self.negative_responses:
print ("Ok, have a nice Earth day!")
return
self.chat()
# Define .make_exit() here:
def make_exit(self, reply):
for word in self.exit_commands:
if word in reply:
print ("Ok, have a nice Earth day!")
return True
# Define .chat() next:
def chat(self):
reply = input(random.choice(self.random_questions)).lower()
while not self.make_exit(reply):
reply = input(self.match_reply(reply))
# Define .match_reply() below:
def match_reply(self, reply):
for key, value in self.alienbabble.items():
intent = key
regex = value
#regex = 'describe_planet_intent'
#reply = input(random.choice(self.random_questions)).lower()
found_match = re.match(regex, reply)
if found_match and intent == 'describe_planet_intent':
return self.describe_planet_intent()
elif found_match and intent == 'answer_why_intent':
return self.answer_why_intent()
elif found_match and intent == 'cubed_intent':
return self.cubed_intent(found_match.groups()[0])
else:
return self.no_match_intent()
# Define .describe_planet_intent():
def describe_planet_intent(self):
responses = ("My planet is a utopia of diverse organisms and species. ", "I am from Opidipus, the capital of the Wayward Galaxies. ")
return random.choice(responses)
# Define .answer_why_intent():
def answer_why_intent(self):
responses = ("I come in peace. ", "I am here to collect data on your planet and its inhabitants. ", "I heard the coffee is good. ")
return random.choice(responses)
# Define .cubed_intent():
def cubed_intent(self, number):
number = int(number)
cubed_number = number * number * number
return (f"The cube of {number} is {cubed_number}. Isn't that cool? ")
# Define .no_match_intent():
def no_match_intent(self):
responses = ("Please tell me more. ", "Tell me more! ", "Why do you say that? ", "I see. Can you elaborate? ", "Interesting. Can you tell me more? ", "I see. How do you think? ", "Why? ", "How do you think I feel when you say that? ")
return random.choice(responses)
# Create an instance of AlienBot below:
my_bot = AlienBot()
my_bot.greet()
I feel like there is a really simple solution to this, I've only been coding for 1 week so this is really new to me, and I appreciate your help :)
The answer is indeed simple. Let's reduce your code to a minimally reproducible one:
def match_reply(self, reply):
for key, value in self.alienbabble.items():
# I omitted the 3 lines that were here - defining 'intent', 'regex_pattern' and 'regex' -
# since at this point they're yet not used
reply = input(self.match_reply(reply)) # oops! self.match_reply is called again!
As you can see, you recursively call self.match_reply without anything to stop it.
EDIT:
There are another 2 things you need to fix:
Let's change match_reply:
a. Let's give it the more appropriate name match_alien_response.
b. Let's make it do what it should: just match a reply. Thus, we don't need it to get another input from the user.
c. Let's make sure it iterates all the keys in alienbabble and doesn't return immediately.
d. We need to use re.findall to get all matches in a string
All these changes give us the following code:
def match_alien_response(self, userReply):
found = False
for intent, regPattern in self.alienbabble.items():
found_match = re.findall(regPattern, userReply)
if found_match and intent == 'describe_planet_intent':
return self.describe_planet_intent()
elif found_match and intent == 'answer_why_intent':
return self.answer_why_intent()
elif found_match and intent == 'cubed_intent':
return self.cubed_intent(found_match[0])
if not found:
return self.no_match_intent()
Inside no_match_intent, it should be responses = instead of responses:

While function using Try not returning the value i thought it should

I am making some homework drill and am trying to check whether a number is a positive integer using Try. somewhere along the way it returns the value of my input, but it returns the negative value, even after I eventually type in a valid value.
lets say- first i typed in -10, it tells me to type again, then I type 2, but the return is still -10.
def takes_desicion(name):
print "Ok %s, now lets make a desicion what to do with your text.\n" %name
print "you can either- 1.leave it, 2.reverse it, or 3.make a new input."
while True:
try: #takes an input with exception- in this case, only integer.
desicion = int(raw_input("Hit your number to decide."))
print desicion
except ValueError:
print "Sorry, thats not a number."
continue
else: #if int is negetive, goes back to the function again, recursively
if desicion < 1:
print "That number is illegal."
takes_desicion(name)
break
return desicion
if i first input -10, and the second input is 2, i would expect the output (return) to be 2. but its -10. That's the value that returns from the function.
You call the takes_desicion function again on third last line, but you don't do anything with the value from that function. You need to store the newly returned value: desicion = takes_desicion(name)
Although you should just use continue instead t jump to the first like of the while loop, there's no need to call the function again:
def takes_desicion(name):
print "Ok %s, now lets make a desicion what to do with your text.\n" %name
print "you can either- 1.leave it, 2.reverse it, or 3.make a new input."
while True:
try: #takes an input with exception- in this case, only integer.
desicion = int(raw_input("Hit your number to decide."))
print desicion
except ValueError:
print "Sorry, thats not a number."
continue
else: #if int is negetive, goes back to the function again, recursively
if desicion < 1:
print "That number is illegal."
continue
break
return desicion

Storing incorrect passwords on .txt file - Python 2.7

I am creating a python program which stores it in a list, then records in a text file called wrongpasswords.txt.
The program should ask the user for input by saying 'Please enter your password: '. The correct password will always be 'rusty' but the user can of course enter any String. And also, how do I add to my program that the number of characters the user inputs wrong is also stored for each incorrect password?
Please do mind me as I am a beginner in programming and python.
Please see my code below:
enteredPass = raw_input("Enter your password: ")
incorrectPass= file("wrongpasswords.txt","w")
counter = 0
for i in range(0, counter+1):
if enteredPass != "rusty":
counter = counter +1
incorrectPassO = open("wrongpasswords.txt","w")
incorrectPassO.write("Incorrect password" +str(counter)+": " + enteredPass + "\n")
incorrectPassO.close()
enteredPass = raw_input("Enter your password: ")
else:
incorrectPassO = open("wrongpasswords.txt","w")
incorrectPassO.write("Correct password entered on the " + str(counter)+"th entry")
incorrectPassO.close()
If I understood correctly you're trying to create a simple login program that counts the wrong login attempts? This should work:
counter = 0
correct_answer_entered = False
while not correct_answer_entered:
enteredPass = raw_input("Enter your password: ")
counter = counter + 1
if enteredPass != "rusty":
incorrectPassO = open("wrongpasswords.txt","a")
incorrectPassO.write("Incorrect password" +str(counter)+": " + enteredPass + "\n")
incorrectPassO.close()
else:
incorrectPassO = open("wrongpasswords.txt","a")
incorrectPassO.write("Correct password entered on the " + str(counter)+"th entry")
incorrectPassO.close()
correct_answer_entered = True
The points I fixed in your code that you should notice:
I replaced the "w" with an "a" where you open the file, since "w" makes it write over what's already wroten in the file, while "a" appends after what's there.
I replaced the for loop with a while, what you did was a range from 0 to 1, so the loop would exit after the first round, I added a boolean value (correct_answer_entered), to indicate if the correct password was entered, and keeps going if it wasn't.
I moved the "counter = counter + 1" outside of the if statement, since the number of attempts is not related to wither the password is correct or not, the way you did it if the password was correct at the first attempt it'd say 0th attempt instead of 1th.
overrall your code is pretty nice and it's good to see new people getting into programming ^.^

Getting error "NameError: name 'letter' is not defined"

I'm fairly new to python and don't know much but i tried to make a program that sees how fast it can guess a string in this case a password. I tried to create an individual variable for each letter by making a loop that sets the variable. (I added the print letter1... at the end so i can see if it works).Then when i went to test it i got this error.
letter[x] = password[x - 1:-(len(password)-1)]
NameError: name 'letter' is not defined
print "Password guesser"
password = raw_input('Enter Password (1-30 carechters only): ')
passwordLength= len(password)
for x in range(0,passwordLength):
letter[x] = password[x - 1:-(len(password)-1)]
print letter1
print letter2
print letter3
Since you're assigning letters with dictionary syntax, you may want to declare the letter variable as a dictionary: letter = {}, then output it as a dictionary. This may get you in the direction you want to go:
letter = {}
for x in range(passwordLength):
letter[x] = password[x - 1:-(passwordLength-1)]
print letter[0]
print letter[1]
print letter[2]

How to declare a variable that spans multiple lines

I'm attempting to initialise a string variable in C++, and the value is so long that it's going to exceed the 80 character per line limit I'm working to, so I'd like to split it to the next line, but I'm not sure how to do that.
I know that when splitting the contents of a stream across multiple lines, the syntax goes like
cout << "This is a string"
<< "This is another string";
Is there an equivalent for variable assignment, or do I have to declare multiple variables and concatenate them?
Edit: I misspoke when I wrote the initial question. When I say 'next line', I'm just meaning the next line of the script. When it is printed upon execution, I would like it to be on the same line.
You can simply break the line like this:
string longText("This is a "
"very very very "
"long text");
In the C family, whitespaces are insignificant, so you can freely use character literals spanning multiple lines this way.
It can also simply be
cout << "This is a string"
"This is another string";
You can write this:
const char * str = "First phrase, "
"Second phrase, "
"Third phrase";