For loops concatenated – beginner python exercise - python

Hi everyone I’m writing because I’m stuck with an exercise in which I should only use for loops and if/else statements. I found a way but practically I’m iterating the same block of code four times and I’m really looking for a way to automate it.
I know that probably this is not the best way to solve the exercise but now I’m not looking for the most efficient way (I already found on the solutions of the exercise), I’m asking you how can I use for to iterate the block of code
The exercise tells me to create a program that takes an IP address from the keyboard and validates that it can be interpreted as a valid IP address.
An IP address consists of 4 numbers, separated from each other with a full stop. Each number can have no more than 3 digits. (Examples: 127.0.0.1)
Important
This challenge is intended to practise for loops, and if/else statements, so although it would probably be written for real using regular expressions we don't want you to use them here even if you know what they are.
This is what I made:
# ipAddress = input("please enter an ipAddress: ")
ipAddress = "192.168.7.7" #test ip address
# check if number of dots is 3
numberOfDot = 0
for char in ipAddress:
if char == '.':
numberOfDot += 1
totNumbOfDot = numberOfDot # output of this section is totNumberOfDot, to be checked at the end
if totNumbOfDot != 3:
print("You inserted a wrong ip address")
# first number check # THIS IS THE BLOCK OF CODE I WANT TO
number1 = '' # ITERATE WITH FOR IF POSSIBLE
for char in ipAddress:
if char in "0123456789":
number1 += char
if char == '.':
break
if 1 <= len(number1) <= 3:
print("First number: OK")
else:
print("First number: Fail")
digitN1 = len(number1) + 1
print(number1)
# second number check
numberMinus2 = ipAddress[digitN1:]
number2 = ''
for char in numberMinus2:
if char in "0123456789":
number2 += char
if char == '.':
break
if 1 <= len(number2) <= 3:
print("Second number: OK")
else:
print("Second number: Fail")
digitN2 = len(number2) + digitN1 +1
print(number2)
# third number check
numberMinus3 = ipAddress[digitN2:]
number3 = ''
for char in numberMinus3:
if char in "0123456789":
number3 += char
if char == '.':
break
if 1 <= len(number3) <= 3:
print("Third number: OK")
else:
print("Third number: Fail")
digitN3 = len(number3) + digitN2 + 1
print(number3)
# fourth number check
numberMinus4 = ipAddress[digitN3:]
number4 = ''
for char in numberMinus4:
if char in "0123456789":
number4 += char
if char == '.':
break
if 0 < len(number4) <= 3:
print("Fourth number: OK")
else:
print("Fourth number: Fail")
digitN4 = len(number4) + digitN3 + 1
print(number4)

I would also say, split() is the way to go. Your question was if there was a way to use your logic and still not have to repeat code 4 times. To achieve that you could do something like this:
numberOfDot=0
number=""
for char in ip+'.':
if char=='.':
numberOfDot+=1
if len(number) in [1,2,3]:
print("number %d OK"%numberOfDot)
else:
print("number %d not OK"%numberOfDot)
print(number)
number=""
elif char in '1234567890':
number+=char
else:
print("character not valid")
if numberOfDot!=4:
print("you inserted a wrong ip")
As i said, i would also recommend using split() - this is just to try and provide an answer closer to your question. Also please note that this code (same as yours) will mark ip adresses containing letters, not only numbers, as OK.

Well, you have to ask yourself the right question: "can I do better?". Please always do that. Yes, in fact, you can. The code that deals with numbers validation between dots is essentially the same. So you should split the string on dots and use for loop to validate each group:
for str in ipAddress.split("."):
your validation here

how about that? split the string at the dots . and check if between the dots there are numbers in the valid range (that would also accept '255.255.255.255')
def valid(ipaddress):
# we need 3 dots; otherwise this is no ipaddress.
if not ipaddress.count('.') == 3:
return False
# check what is before, between and after the dots
for byte in ipaddress.split('.'):
# if byte can not be interpreted as an integer -> no good!
try:
i = int(byte)
except ValueError:
return False
# now check if byte is in the valid range
if i < 0:
return False
if i > 255:
return False
return True
print(valid(ipaddress='192.168.7.7')) # -> True
print(valid(ipaddress='.168.7.7')) # -> False
print(valid(ipaddress='721.168.7.7')) # -> False

Related

How to break while loop when two conditions are true - Calculator

I'm building my first calculator. Trying to implement While loop to get a number through user input. I want the While to break once user put a number.
num1 = raw_input("Add mumber one: " )
try:
input = int(num1)
except ValueError:
print "This is not a number"
attempt = 0
while type(num1) != int and attempt < 5:
num1 = raw_input("Add Number one again: " )
attempt += 1
break
print "You are not putting number. So, goodbuy"
operation = raw_input("Add Operator: ")
Try this:
for _ in range(5):
num1 = unicode(raw_input("Add number one: "))
if num1.isnumeric():
break
Another method you can try is to have num1 and do the following in the while loop:
if type(num1) is int:
break
What this does is check the type of the variable num1. If it is an integer, int, then it breaks out of the while loop.
I want the While to break once user put a number.
You already are doing that in the condition for your while loop by having type(num) != int so your while loop should stop after the user enters an integer.
You have several errors here:
while type(num1) != int and attempt < 5:
num1 = raw_input("Add Number one again: " )
attempt += 1
break
The break statement shoud be inside the loop, but the indentation is wrong. As you write, it is after the loop (hence useless). Also, when you read from standard input, you always get a string even if it is a number. So when you check type(num1) != int this is always false. You must convert num1 with int() each time you read from standard input, not only the first time:
while True:
num1 = raw_input("Add Number one again: " )
try:
input = int(num1)
break
except ValueError:
print "This is not a number"
if attempt == 5:
break
attempt += 1
Here I try to convert to an integer the string read from stdin. If it works, I break the loop immediately. If it does not work (the except clause) I check how many attempts have been done, and break the loop if the attempts are equal to 5.

Getting an "invalid literal for int with base 10" in Python

import random
print("Welcome to RNG Guesser!\n")
gld = random.randrange(1,10)
counter = 0
ccounter = 0
while True:
print("Number of tries: {}".format(counter))
print("Number of correct guesses: {}".format(ccounter))
num = input("Enter a number: ")
if num is "exit":
print("Number of tries: {}".format(counter))
print("Number of correct guesses: {}".format(ccounter))
break
else:
if int(num) is gld:
print("Congratulations, your guessed number {} was right!".format(num))
counter += 1
ccounter += 1
elif int(num) < gld:
print("Pick a higher number!")
counter += 1
else:
print("Pick a lower number!")
counter += 1
Why am I getting the "invalid literal for int" when I type in exit? I tried converting the input variable to int, I tried with an else statement, I tried making 2 variables, one for string one for int, and none of them worked.
I believe the issue is from the line:
if num is "exit"
Is evaluating to False and further down the script when Python tries to convert the literal string exit to an int, it will fail.
Try replacing is with ==
The problem is that is compares two objects to see if they are the same, whereas what want to is to see if the tow objects' values are the same. Check this stack overflow thread for more info.
Assuming that the incorrect indentation in the question is just a copy-paste mistake... try this:
x = input('enter x > ')
print('x == "exit": {}'.format(x == "exit"))
print('x is "exit": {}'.format(x is "exit"))
Here's what happens:
enter x > exit
x == "exit": True
x is "exit": False
Or maybe:
x is "exit": True
The is operator compares object identity but you are trying to compare the contents of two strings.
Note that you cannot give a string with non-numeric characters to int().
Now num is supposed to be a str, and it could be anything from user input. Also note that when you want to evaluate two values, use == instead of is. is is supposed to be used as judging if two things are the same object.
If you want to use if-else, try this:
if num == "exit":
print("Number of tries: {}".format(counter))
print("Number of correct guesses: {}".format(ccounter))
break
elif not num or not all(char.isdigit() for char in num):
print("You are not giving a number.")
else:
if int(num) == gld:
print("Congratulations, your guessed number {} was right!".format(num))
counter += 1
ccounter += 1
elif int(num) < gld:
print("Pick a higher number!")
counter += 1
else:
print("Pick a lower number!")
counter += 1
Here, all(char.isdigit() for char in num) is checking for every character in num to see if they are all numbers. We should be aware that anything could appear in user's input. Only numbers can be converted to int.
We have another solution which is more clear and simple. You may need to read some documents on try...except... in Python.
try:
if int(num) ...
except ValueError:
# num is not able to be converted to int
print("You are not giving a number.")

Check for a string in if-statement

I have a program with some user inputs and I need to check if what the user entered was a string or an integer value between 1 and 10 million.
My code looks like this (simplified):
while True:
inp = raw_input("Enter a value between 1 and 10 million: ")
if inp < 1:
print "Must be higher than 1"
continue
elif inp > 10.000.000:
print "Must be less than 10.000.000"
continue
elif 'inp is a string': #here's my problem
print "Must be an integer value!"
continue
else:
'execute the rest of the code'
I don't know how to solve this. My program always terminates when I enter a string by mistake.
Thank you!
First, you're using Python 2, which will happily compare strings to integers. You don't want to do that. Secondly, raw_input() will always return a string. What you're hoping to do is check if that string could possibly represent a number. Third, 10.000.000 is improper syntax. Don't use separators. Fourth, you only need to continue if you want to go to the top of the loop early. If everything's in an if..elif..else block at the end of the loop, only one of those will be executed, so you don't need to put a continue at the end of each branch. You can use continue statements or restructure your branch. Finally, don't use in as a variable name, because that's a Python keyword.
while True:
inp = raw_input("Enter a value between 1 and 10 million: ")
if not inp.isdigit():
print "Must be an integer value!"
continue # each of these continue statements acts like a "failed, try again"
inp = int(inp)
if inp < 1:
print "Must be higher than 1"
continue # same for this one
if inp > 10000000:
print "Must be less than 10.000.000"
continue # and this one
# execute the rest of the code
You can use .isdigit() to check if string consists of numbers to make sure it can be convertible to integer:
while True:
in = raw_input("Enter a value between 1 and 10 million: ")
if in.isdigit():
number = int(in)
if number < 1:
print "Must be higher than 1"
continue
elif number > 10**6:
print "Must be less than 10.000.000"
continue
else:
'execute the rest of the code'
else:
print "Must be an integer value!"
continue
I have no idea how you came up with your code but here are different suggestions:
Don't use "in" as variable name because it's a python operator.
After the input you can check whether it is an int or a string.
Your program can look like this:
while True:
try:
input_int = int(raw_input("Enter a value between 1 and 10 million: "))
if input_int < 1 :
print "Must be higher than 1"
elif input_int > 10**7:
print "Must be less than 10.000.000"
except:
print "Must be an integer value!"
else: #You can use else with try/except block
#'execute the rest of the code'
Voilà

ISBN Checker - validating user input

So, my task is to validate the user's input for each of the ISBN 10 digits that they input. I need to make sure that 1) the user input isn't blank, 2) the user input is only an integer (which I've done), and 3) that they only enter ONE digit.
Sorry, I have seen a few similar questions on this, but I wanted to keep the try-except statement (if possible) so the similar questions weren't too helpful.
How can I go about validating against blank inputs and that only one digit is entered?
Here is the code:
print("You will be asked to enter an ISBN-10 Number. Please enter it digit by digit.")
ISBN10NumberList = []
ISBN10NumberAdder = 0
for count in range (10):
validInput1 = True
if (count <= 8):
while validInput1 != False:
try:
ISBN10NumberList.append(int(input("Please enter the ISBN digit: ")))
validInput1 = False
except ValueError:
print("That is not a valid input! Please enter a integer only.")
elif (count == 9):
CheckDigit10 = input("Please enter the ISBN digit: ")
print("")
if CheckDigit10 == "X" or CheckDigit10 == "x":
CheckDigit10 = 10
for count in range (0, 9):
ISBN10NumberAdder += int(ISBN10NumberList[count]) * (10 - count)
CheckDigit10 = int(CheckDigit10)
CheckingCheckDigit = 11-(ISBN10NumberAdder % 11)
if (CheckDigit10 == CheckingCheckDigit):
print("This is a valid ISBN!")
else:
print("This is not a valid ISBN!")
So yes - you are making life hard for yourself and your user - here is a simpler implementation where the user can enter the ISBN in one fell swoop. I factored out some things into functions to make things a little cleaner
In the main loop, the user will be repeatedly prompted for an ISBN until they enter a valid one
def verify_check(isbn_str):
last = isbn_str[-1] # Last character
if last == 'X':
check = 10
else:
check = int(last)
# This part was fine in your original:
adder = 0
for count in range(9):
adder += int(isbn_str[count]) * (10 - count)
if adder % 11 != check:
raise ValueError("Checksum failed")
def verify_isbn10(isbn_str):
if len(isbn_str) != 10:
raise ValueError("ISBN must be 10 digits long")
# Check that the first nine chars are digits
for char in isbn_str[:-1]:
if not char.isdigit():
raise ValueError("ISBN must contain digits or X")
# Special case for the last char
if not (isbn_str[-1].isdigit or isbn_str[-1] == "X"):
raise ValueError("ISBN must contain digits or X")
verify_check(isbn_str)
# Main code:
while 1:
try:
isbn_str = raw_input("Enter ISBN: ")
verify_isbn(isbn_str)
break
except ValueError as e:
print "Whoops:", e
# At this point, isbn_str contains a valid ISBN
If you want to use Kevin's suggestion and try your hand at regexes, you can use something like the following replacement for verify_isbn10. Note that it doesn't explain to the user exactly what was wrong.
import re
isbn_re = re.compile(r"""
^ #Start of string
[0-9]{9} # Match exactly 9 digits
[0-9X] # Match a digit or X for the check digit
$ # Match end of string
""", re.VERBOSE)
def verify_isbn10(isbn_str):
m = isbn_re.match(isbn_str)
if m is None: #User didn't enter a valid ISBN
raise ValueError("Not a valid ISBN")
verify_check(isbn_str)

Making a Parentheses program? I'm stuck

This is Python. I'm trying to write a program that asks the user for a string input without using global variables. If the string has parentheses only side by side, then it's even. if it has letters, numbers, or the parentheses are spaced out, then it's uneven. For example, () and ()() and (()()) is even, whereas (() and (pie) and ( ) is not. Below is what I've written so far. My program keeps on printing 'Enter your string' infinitely, I'm stuck with that problem right now.
selection = 0
def recursion():
#The line below keeps on repeating infinitely.
myString = str(input("Enter your string: "))
if not myString.replace('()', ''):
print("The string is even.")
else:
print("The string is not even.")
while selection != 3:
selection = int(input("Select an option: "))
#Ignore this.
if selection == 1:
print("Hi")
#This won't work.
elif selection == 2:
def recursion():
recursion()
This outputs the correct even/not even answers.
selection = 0
def recursion():
myString = str(raw_input("Enter your string: ")) #Use raw_input or ( ) will be ()
paren = 0
for char in myString:
if char == "(":
paren += 1
elif char == ")":
paren -= 1
else:
print "Not Even"
return
if paren < 0:
print "Not even"
return
if paren != 0:
print "Not even"
return
print "Even"
return
while selection != 3:
selection = int(input("Select an option: "))
#Ignore this.
if selection == 1:
print("Hi")
#This won't work.
elif selection == 2:
recursion() #This isn't a recursive function - naming it as so is...
Unless you're using Python 3, you should use raw_input instead of input, because input gives back the result in whatever type matches the input best, whereas raw_input always returns a string. In Python 3, input always returns a string. Also, why are you redefining recursion? Just call it from the elif statement. Example:
selection = 0
def recursion():
#The line below keeps on repeating infinitely.
myString = raw_input("Enter your string: ") # No need to convert to string.
if not myString.replace('()', ''):
print("The string is even.")
else:
print("The string is not even.")
while selection != 3:
selection = int(raw_input("Select an option: "))
#Ignore this.
if selection == 1:
print("Hi")
#This won't work.
elif selection == 2:
recursion() # Just call it, as your program already
# recurs because of the if statement.

Categories