Python if statement using CSV Data - python

I am reading in some data from a CSV file and then printing a value based on an if statement, but it doesn't seem to make sense to me. I would expect it would print equal to 1
PYTHON CODE:
import csv
#open CSV file
csvfile = open("C:\\python.csv", "rb")
data = csv.reader(csvfile)
data = [row for row in data]
#start loop through each item
for currentrow in range(1, 2): # numbers off due to array starting at 0
#grab one record data [row][col]
Count = data[currentrow][7]
print "Count equals: " + Count
if Count > 1:
print "greater than 1"
if Count == 1:
print 'equal to 1'
OUTPUT:
Count equals: 1.00
greater than 1

Your trouble stems from the fact that what you read from a file is always a string (i.e. str type). This means that even if the file contains a number, it is read into your variable as a string. Therefore, if your file looks like this:
myFile.txt:
2
And if you did:
with open('myFile.txt') as infile:
x = infile.readline()
then, x would have the value '2', which is a str type. This means, that if you did x*2, you'd get '22', because that's how strings multiply out.
What you really want, is to convert that sting into an int. This is called "casting a string into an integer" and can be done very simply:
y = int(x)
There's another type that you should be aware of: float. It is used to hold decimal numbers. So, if you were to say
x = 3.4
then x would be a float. You can also cast ints to floats:
z = float(y)
would turn z into a float, with the value 2.0
Now, onto your actual problem:
data = [row for row in data] # data is now a list of lists; each sublist is a list of strings
for currentrow in range(1,2):
Count = data[currentrow][7] # Count is now the string at index 7, of the sublist at index `currentrow`, i.e. 1.00
Count = float(Count) # Count is now the floating point value of the string '1.00'
Count = int(Count) # Count is now the integer value of 1.00, i.e. 1
if Count > 1:
print "greater than 1"
if Count == 1:
print "equal to 1"
Now, onto your second problem:
print 'Count equals ' + Count
Here, you are trying to add a str and an int. Well, those are incompatible types for addition. Therefore, you should cast the int into a str; and just like how strs can be cast into ints, ints can be cast into strs with a call to str():
Count_str = str(Count)
So when you want to print the value, you could do:
print "Count equals " + str(Count)
Of course, the print statement is a little more friendly and lets you do something like this:
print "Count equals", Count # no casting needed here

Related

convert a string from a list to a float

I have a list with strings. Some of the strings contain alphabets and some contain numbers. I want to convert one of the strings with numbers in it to a float but getting an error
the list is called x. the 3rd element of the list is numbers. I tried x[2] = float (x[2]) but it gives me :Value error: could not convert string to a float:%"
See line 12 of the code where I am comparing float(x[2]) with 100
def file_read(fname):
i = 0
content_array = []
with open(fname, 'r') as f:
#Content_list is the list that contains the read lines.
for line in f:
content_array.append(line)
x = content_array[i].split('|')
i = i + 1
x[2] = x[2].strip() # to delete any empty spaces
if float(x[2]) > 50.00:
print ('got one')
print x[2]
print i
file_read('flow.txt')
Around your if statement you can wrap a try/except block, the program will try to convert float(x[2]) to a float, but if it cannot (since its a string) it will execute the except portion of the code.
try:
if float(x[2]) > 50.0:
print('got one')
except:
# do something else, if x[2] is not a float
pass # if you don't want to do anything.
You can use regular expressions to check if it's a number, and then you can safely cast it to float.
import re
rgx = "^\d*\.?\d*$"
if re.match(rgx, x):
print("it's a number!")
x = float(x)

list index out of range in simple Python script

I just started learning Python and want to create a simple script that will read integer numbers from user input and print their sum.
The code that I wrote is
inflow = list(map(int, input().split(" ")))
result = 1
for i in inflow:
result += inflow[i]
print(result)
It gives me an error
IndexError: list index out of range
pointing to result += inflow[i] line. Can't see what am I doing wrong?
BTW, is there more elegant way to split input flow to the list of integers?
You can also avoid the loop altogether:
inflow = '1 2 34 5'
Then
sum(map(int, inflow.split()))
will give the expected value
42
EDIT:
As you initialize your result with 1 and not 0, you can then also simply do:
sum(map(int, input.split()), 1)
My answer assumes that the input is always valid. If you want to catch invalid inputs, check Anton vBR's answer.
Considering: I just started learning Python
I'd suggest something like this, which handle input errors:
inflow = raw_input("Type numbers (e.g. '1 3 5') ") #in py3 input()
#inflow = '1 2 34 5'
try:
nums = map(int, inflow.split())
result = sum(nums)
print(result)
except ValueError:
print("Not a valid input")
for i in list gives the values of the list, not the index.
inflow = list(map(int, input().split(" ")))
result = 1
for i in inflow:
result += i
print(result)
If you wanted the index and not the value:
inflow = list(map(int, input().split(" ")))
result = 1
for i in range(len(inflow)):
result += inflow[i]
print(result)
And finally, if you wanted both:
for index, value in enumerate(inflow):
script that will read integer numbers from user input and print their
sum.
try this :
inflow = list(map(int, input().split(" ")))
result = 0
for i in inflow:
result += i
print(result)
If you were going to index the list object you would do:
for i in range(len(inflow)):
result += inflow[i]
However, you are already mapping int and turning the map object into a list so thus you can just iterate over it and add up its elements:
for i in inflow:
result += i
As to your second question, since you arent doing any type testing upon cast (i.e. what happens if a user supplies 3.14159; in that case int() on a str that represents a float throws a ValueError), you can wrap it all up like so:
inflow = [int(x) for x in input().split(' ')] # input() returns `str` so just cast `int`
result = 1
for i in inflow:
result += i
print(result)
To be safe and ensure inputs are valid, I'd add a function to test type casting before building the list with the aforementioned list comprehension:
def typ(x):
try:
int(x)
return True # cast worked
except ValueError:
return False # invalid cast
inflow = [x for x in input().split(' ') in typ(x)]
result = 1
for i in inflow:
result += i
print(result)
So if a user supplies '1 2 3 4.5 5 6.3 7', inflow = [1, 2, 3, 5, 7].
What your code is doing, in chronological order, is this:
Gather user input, split per space and convert to integer, and lastly store in inflow
Initialize result to 1
Iterate over every item in inflow and set item to i
Add the current item, i to result and continue
After loop is done, print the result total.
The broken logic would be at step 4.
To answer your question, the problem is that you're not gathering the index from the list as expected-- you're iterating over each value in the list opposed to the index, so it's really undefined behavior based on what the user inputs. Though of course, it isn't what you want.
What you'd want to do is:
inflow = list(map(int, input().split(" ")))
result = 1
for i in range(len(inflow)):
result += inflow[i]
print(result)
And on your last regard; there are two real ways to do it, one being the way you're doing right now using list, map and:
inflow = [int(v) for v in input().split()]
IMO the latter looks better. Also a suggestion; you could call stdlib function sum(<iterable>) over a list of integers or floats and it'll add each number and return the summation, which would appear more clean over a for loop.
Note: if you're splitting per whitespace you can just call the str.split() function without any parameters, as it'll split at every whitespace regardless.
>>> "hello world!".split()
['hello', 'world!']
Note: also if you want extra verification you could add a bit more logic to the list comprehension:
inflow = [int(v) for v in input().split() if v.isdigit()]
Which checks whether the user inputted valid data, and if not, skip past the data and check the following.

Incrementing an integer by +1 and adding to string

Trying to create an integer that starts at 0000 and increments by +1 (0001 etc) and then adds it to a string until the number reaches 9999. How could i do this?
for x in range(10000):
print(str(x).rjust(4, '0'))
You stated that you want to add them to a URL so the way to do it would be:
url = "thisisanamazingurl{0:0>4}" # insert your URL instead of thisisanamazingurl
for i in range(10000):
tempurl = url.format(i)
print(tempurl) # instead of print you should do whatever you need to do with it
This works because :0>4 fills the "input string" with leading zeros if it's shorter than 4 characters.
For example with range(10) this prints:
thisisanamazingurl0000
thisisanamazingurl0001
thisisanamazingurl0002
thisisanamazingurl0003
thisisanamazingurl0004
thisisanamazingurl0005
thisisanamazingurl0006
thisisanamazingurl0007
thisisanamazingurl0008
thisisanamazingurl0009
or if you want to store them as a list:
lst = [url.format(i) for i in range(10000)]
num = ""
for number in range(10000):
num = num + str('%04d' % number)
print num
This will iterate through every number between 0 and 9999 and append it to the num string. The '%04d' bit forces it to use 4 numeric places with the leading zeros.
(As an aside, you can change the ending number by changing the value of the number in the range function.)
Since you want to add it to a string, I am going to assume you want the type of the 4 digit number as string .
So you can do(python3.x) :
string=''
for x in range(10000):
digit= '0'*(4- len(str(x)) + str(x)
string+=digit

I want to write a code that can take two numbers and create a txt file between those numbers in decreasing order

here is the code
import os
myfile = ('filename.txt' ,'wb')
a = int(input('integer a: '))
b = int(input('integer b: '))
def cal(a,b):
while a>b:
a = a-1
print a
c = str(cal(a,b))
print c
myfile.writelines(c)
I am getting only last word written in file. please someone help me.
Even if you returned a at the end of your cal function you would just get one number being written. You can do the whole thing a lot easier by using a range and converting it to a list, then joining that list with a space
import os
smallNum= int(input('smaller integer a: '))
bigNum= int(input('bigger integer b: '))
with open('filename.txt' ,'w') as myFile:
myFile.write(" ".join([str(x) for x in list(range(smallNum+1,bigNum))]))
This line of code creates a range of all the numbers in between your two nums:
range(bigNum+1,smallNum)
Then convert to a list (of ints)
list(range(bigNum+1,smallNum))
Then convert that to a list of strings with a list comprehension
[str(x) for x in list(range(bigNum+1,smallNum))]
Finally join each item in the list with a space
" ".join([str(x) for x in list(range(bigNum+1,smallNum))])
A solution that doesn't use list comprehensions / .join / context managers
import os
smallNum = int(input('smaller integer a: '))
bigNum = int(input('bigger integer b: '))
writeString = "" #string to write to file later
for currentNum in range(smallNum+1, bigNum): #non-inclusive range of numbers
strNum = str(currentNum) #convert to string
writeString += strNum + " " #add the number and a space to the string
file = open("filename.txt", "w")
file.write(writeString)
file.close()

Python: unorderable types: int() < range() or 'int' object is not iterable

I'm trying to get a python script to print '#' symbols, in relation the the value held in a list. For example, if the list as [1,2,3] - the script would print:
1 #
2 ##
3 ###
With the following code:
myList = [0,1,2,3,4,5,6]
x = 1
While x < range(len(myList)):
print (x, end ='')
for frequency in myList[x]:
print ('#')
print ('\n')
x = x + 1
So far I get this error "TypeError: unorderable types: int() < range()". I think I'm getting this because it can't compare a single number to a range of numbers.
But when I try to just use:
len(myList)
I get: "TypeError: 'int' object is not iterable".
Not sure what to do!
As the error says, this is comparing the value in x to the value range(...):
while x < range(len(myList)):
print (x, end ='')
That's not what you want. Instead, you want to loop across those values:
for x in range(len(myList)):
...
Similarly, your second loop isn't going to work:
for frequency in myList[x]:
print ('#')
Since myList[x] is an int, that translates as "for every value frequency in the the number myList[x]..." which doesn't really make sense. You really mean:
for frequency in range(myList[x]):
print ('#')
Please throw your code in the dustbin and look for a better approach
You'd better do this:
for number in yourList:
if number <= 0:
print("Cannot use negative numbers or zero here!")
else:
print ("{} {}".format(number, "#" * number))
Don't forget that you can get N copies of a string by simply multiplying this string by N, where N is a positive non-zero number.
You're getting the error because you are actually comparing an int to a range object on this line:
while x < range(len(myList)):
To get the output you desire, it would be much easier to just multiply strings:
for i in range(7):
print(i, i * '#')
Adjust the call to range if you want to omit the zero row.
You can use a for loop to do this:
>>> myList = [0,1,2,3,4,5,6]
>>> for item in myList:
... if item > 0:
... print(item, '#' * item)
...
1 #
2 ##
3 ###
4 ####
5 #####
6 ######
In python you can use the '*' operator to print strings multiple times, like a kind of multiplication.
If you want output a zero but no '#' when the item is zero, remove the if item > 0: and dedent the line that follows it.

Categories

Resources