Python: Ignoring empty lines when identifying happy numbers - python

The task (from codeeval) is to read a file that has a few different numbers, and print 1 if it is a happy number or print 0 if it is not a happy number. Part of the task is to ignore the item (num) if it is an empty line. Here is my code:
import sys
test_cases = open(sys.argv[1], 'r')
for num in test_cases:
if num=="":
pass
else:
liszt=[]
while num>1:
newnum=str(num)
total=0
for i in newnum:
total+=int(i)**2
if total not in liszt:
liszt.append(total)
num=total
else:
print 0
break
else:
print 1
test_cases.close()
I get an error message that references the total+=int(i)**2 line, saying this:
ValueError: invalid literal for int() with base 10: ''
Which makes me think I'm not being successful in ignoring empty lines. Am I on the right track? If so, what change should I make to the code?
Thanks for your help!

In order to make sure you don't deal with empty lines and new lines, you can simply add:
if num.strip():
num = num.rstrip('\n')
# DO SOMETHING HERE...
# ...
So you'll get:
import sys
test_cases = open(sys.argv[1], 'r')
for num in test_cases:
if num.strip():
num = num.rstrip('\n')
# DO SOMETHING HERE...
# ...
test_cases.close()

Related

Find the last element (digit) on each line and sum all that are even python 3

Hi there Stack Overflow!
I'm trying to solve an assignment we got in my Python class today. I'm not super familiar with python yet so I could really need some tips.
The task is to:
Find the last element (digit) on each line, if there are any, and sum all
that are even.
I have started to do something like this:
result = 0
counter = 0
handle = open('httpd-access.txt')
for line in handle:
line = line.strip()
#print (line)
if line[:-1].isdigit():
print(line[:-1].isdigit())
digitFirst = int(line[counter].isdigit())
if digitFirst % 2 == 0:
print("second")
result += digitFirst
else:
print("else")
ANSWER = result
But this code doesnt work for me, I don't get any data in result.
What is it that i'm missing? Think one problem is that I'm not going through the line element by element, just the whole line.
Here is an example of how I line in the file can look:
37.58.100.166--[02/Jul/2014:16:29:23 +0200]"GET/kod-exempel/source.php?dir=codeigniter/user_guide_src/source/_themes/eldocs/static/asset HTTP/1.1"200867
So the thing I want to retrieve is the 7. And then I want to do a check if the seven is a even or odd number. If it's even, I save it in the a variable.
Don't even bother with the isdigit. Go ahead and try the conversion to int and catch the exception if it fails.
result = 0
with open('httpd-access.txt') as f:
for line in f:
try:
i = int(line.strip()[-1:])
if(i % 2 == 0):
result += i
except ValueError:
pass
print('result = %d' % result)
isdigit() return True or False, which is assigned to digitFirst (try print it!).
True and False are evaluated as 0 and 1 (respectively) in math operations.
So, it always pass the if digitFirst % 2 == 0 when digitFirst is 0, which means 0 always gets added to result.
Also, notice that counter is always 0 during the for loop and gets raised to 1 only after it, which means you are always working with the first letter of every line.
The purpose of counteris unclear as it only used as "the index of the letter you get" each line.
result = []
with open('https-access.txt') as fin:
for line in fin:
l = line.strip()
if l[-1].isdigit():
if int(l[-1]) % 2 == 0:
result.append(int(l[-1]))
ANSWER = sum(result)
How does your file look? You want to calculate the last digit on each line if it's even number. In your code "line[counter]" will catch the first index of each line.
For example if data in file is as follows:
some_data 2
since counter is set to 0, therefore line['counter'] in your code will always check the first index which will be 's' in the example above.
If you can post a few lines from the file that you will be opening, I may be able to suggest something.

Cannot concatenate 'str' and 'int' objects but I can run it fine through my own IDLE?

I'm running on Python 2.7.10 with the following code:
import sys
with open(sys.argv[1], 'r') as input:
test_cases = input.read().strip().splitlines()
for test in test_cases:
orig_number = test
iteration = 0
while True:
if str(orig_number) == str(orig_number)[::-1]:
print iteration, orig_number
break
iteration += 1
orig_number = orig_number + int(str(orig_number)[::-1])
And it will run without a hitch but running it on Code Eval on Python 2.7.3 It keeps returning a
cannot concatenate 'str' and 'int' objects
On the last line but I can't figure out why it's returning that as both parts seem to be an int.
I am not sure where this is working, but clearly orig_number is not an int . When you read stuff from a file , and then do strip() / splitlines() on it, you get back a list of strings.
Hence, in the for loop, test is a string, and hence orig_number is also a string.
You do not need to convert them to str explicitly and you should convert the orig_number to int before trying to add, and then convert them back to str to save in orig_number. Example:
import sys
with open(sys.argv[1], 'r') as input:
test_cases = input.read().strip().splitlines()
for orig_number in test_cases:
iteration = 0
while True:
if orig_number == orig_number[::-1]:
print iteration, orig_number
break
iteration += 1
orig_number = str(int(orig_number) + int(orig_number[::-1]))
You are looping over test_cases which contains strings so first of all you don't need to convert it to string with str and you need to convert it to int as the end of code.
Also instead of reading and stripping and then using splitline you can simply as a more pythonic way just loop over your file object :
import sys
with open(sys.argv[1], 'r') as input:
for test in input:
orig_number = test.strip()
iteration = 0
while True:
if orig_number == orig_number[::-1]:
print iteration, orig_number
break
iteration += 1
orig_number = int(orig_number) + int(orig_number[::-1])
Also note that since converting the string to int may raise an exception you can handle such problems with a try-except statement.
try:
orig_number = int(orig_number) + int(orig_number[::-1])
except ValueError:
# raise exception or do stuff

I have a file with letters and numbers and I want to segregate out the numbers

I have a file with letters and numbers and I want to segregate out the numbers
I tried out the following code, but it fails:
n_file = open("text.txt","br+")
num = ""
while(1):
cch = n_file.read(1)
if(len == n_len):
break
if(cch != '\n'):
n_len = n_len + 1
if(re.findall("[0-9]", cch):
num = num + text
print(num)
It says:
print("Check This",(int)cch)
^
SyntaxError: invalid syntax
It is invalid syntax because you are trying to do a cast a la Java. Try to print int(cch).
By the way, why are you doing while(1) and then check if len == n_len to do a break? Why do you not use these values in the while itself? Like, while(n_len < len)
Apart from that, you can simplify a lot your code. Something like (I didn't try this code, so any bug just try to figure out what is happening):
num = ''
with open("text.txt","r") as file:
for char in file.readline():
if char.isdigit():
num += char
print int(num)
I don't know if you want to read the file until a limit len is achieved. if so you need to have a counter after the char.isdigit() and stop when this len is achieved. And close the file is always a good practice, I'm not seeing you closing it. The with statement do that for you.

Reading a file until a match found with python

I have been trying this code to loop through randomly until a match found in the lookin.txt file and stop when a match is found with no success as my Python knowledge not that brilliant. Code is working only once but i need it to run continously until it finds a match. I appreciate if someone can direct me in the right direction.
#! /usr/bin/env python
import random
randrange = random.SystemRandom().randrange
z = randrange( 1, 1000)
target_f = open("lookin.txt", 'rb')
read_f = target_f.read()
if z in read_f:
file = open('found.txt', 'ab')
file.write(z)
print "Found ",z
else:
print "Not found ",z
Lookin.txt:
453
7
8
56
78
332
you need to use while and change the random number:
#!/usr/bin/env python
import random
target_f = open("lookin.txt", 'rb')
read_f = target_f.read()
while True: # you need while loop here for looping
randrange = random.SystemRandom().randrange
z = str(randrange( 1, 1000))
if z in read_f:
file = open('found.txt', 'ab')
file.write(z)
file.close()
print "Found ",z
break # you can break or do some other stuff
else:
print "Not found ",z
import random
running=True
while running:
a=random.randint(1,1000)
with open ("lookin.txt") as f:
rl=f.readlines()
for i in rl:
if int(i)==a:
print ("Match found")
with open("found.txt","w") as t:
t.write(str(a))
running=False
Try this.Also with open method is better for file processes. If you want to only one random number, than you can just put the a variable outside of while loop.
The "z = randrange(1,1000)" gives you one random number and the rest of your script reads the entire file and tries to match that number against the file.
Instead, enclose place the script into a loop for it to keep trying.
import random
randrange = random.SystemRandom().randrange
while True:
z = randrange( 1, 1000)
DO YOUR SEARCH HERE
The while True will cause your script to run forever so depending on what you are trying to accomplish, you'll need to add an "exit()" someplace for when you want the program to end.
Also, your "if z in read_f" line fails because it expects a string and not the integer value from the random number generator. Try "if str(z) in read_f:"
We can get only integer value from target file(used with statement to read file) and create dictionary which get constant time for key search.
Apply while loop to find random number into file i.e. in created dictionary.
If random number found in the dictionary then add to found.txt and break code.
If not found random number then continue for next random number.
import random
randrange = random.SystemRandom().randrange
with open("lookin.txt", 'rb') as target_f:
tmp = [int(i.strip()) for i in target_f.read().split('\n') if i.isdigit() ]
no_dict = dict(zip(tmp, tmp))
while 1:
z = randrange( 1, 1000)
if z in no_dict:
with open('found.txt', 'ab') as target_f:
target_f.write("\n"+str(z))
print "Found ",z
break
else:
print "Not found ",z
Note: If target file not contains any integer in between random number range then code will go into infinite loop.

python read files and stop when a condition satisfies

I am trying a program where it reads all files in a directory and when the 'color=brown' is attained then my program has to stop reading even if finds 'color=brown' in the next file.I mean,the condition first met should only be taken.
I tried a program where it prints all the color=brown from all the files,but i have to stop after its first read. Please help!
import os
path = r'C:\Python27'
data = {}
for dir_entry in os.listdir(path):
dir_entry_path = os.path.join(path, dir_entry)
if os.path.isfile(dir_entry_path):
with open(dir_entry_path, 'r') as my_file:
for line in my_file:
for part in line.split():
if "color=brown" in part:
print part
please help!answers will be appreciated!
you can set a variable stating that you are done and then break out of each loop
but depending on the nesting of the loop it might be cleaner to use an exception to jump out of the loop (kind of like a goto in C):
try:
for m in range(10):
for n in range(10):
if m == 5 and n == 15:
raise StopIteration
except StopIteration:
print "found"
else:
print "not found"
print "always runs unless the other clauses return"
You're looking for the break statement.
...
if "color=brown" in part:
print part
# set some variable to check at the last thing before your other for loops
# turnover.
br = True
break
and then use that to break out of every other two for loops you've initiated.
if br == True:
break
else:
pass
if br == True:
break
else:
pass

Categories

Resources