I'm just starting out with programming, and I know I'm still missing some of the basics, but I'm trying to work this out. I have a list of 3 and 4 digit numbers that I've brought in from a text file, and I'm trying to get a sum of these numbers. So far all I can get python to do is perform a sum of each individual number, so if the first number in the list is 427, it's printing 13, rather than adding 427 + 504 + 219, etc.
This is what I have:
myList = []
inFile = open('E:/GIS/GTECH 731/NYCElementarySchools.txt', 'r')
for row in inFile:
col = row.split('\t')
if col[1]=='BK':
myList = (col[3])
intList = [int(x) for x in myList]
print sum(intList)
Additionally, when i have it print length, it gives me a list of 3's and 4's, telling me the length of each number, not giving me the total count of numbers.
I must be missing something fundamental, but I don't know what it is! Any suggestions are appreciated! Thanks!
This:
myList = (col[3])
will set myList to a str, not a list, which would be a representation of a number. Thus:
intList = [int(x) for x in myList]
would convert the digits to numbers. You want int(myList) to convert the whole string to a number.
You can keep a running total (initialised to 0) and do total += int(myList) to total all of the numbers. Then after the loop you can print the result.
In your code:
col = row.split('\t')
if col[1]=='BK':
myList = (col[3])
intList = [int(x) for x in myList]
print sum(intList)
'col = row.split('\t')' makes a list which is divided by TAB.
If the line which is read from the file, looks like this:
# \t is TAB
SOMETHING\tBK\t1\t2\t3
The col structure is:
col[0] = SOMETHING
col[1] = BK
col[2] = 1
col[3] = 2
col[4] = 3
So, if you intend sum col[3] to col[...] then use col[3:] = list of col[3], col[4]
Thus, if you want to accumulate sum result you need another variable.
myList = []
inFile = open('E:/GIS/GTECH 731/NYCElementarySchools.txt', 'r')
sumList = []
for row in inFile:
row_total = 0
col = row.split('\t')
if col[1]=='BK':
intList = [int(x) for x in col[3:]]
row_sum = sum(intList)
# row_sum = map(lambda x: int(x), col[3:])
print 'row total: %d' % (row_sum)
sumList.append(row_sum)
print 'total: %d' % (sum(sumList))
Probably you want to use a slice to assign myList
myList = col[3:]
this will return a list everything from the 3rd column on.
Related
sf = input('pick a number between 1-5: ')
string = ''
with open('dna.txt','r')as f:
count = 0
for line in f:
row = list(map(str, line.strip().split()))
Letter, number = row
n=int(number)
chunks = [row[x:x+2] for x in range(0, len(row),2)]
for x in chunks:
print(x)
if x >= sf:
string += x
After getting a user input, it needs to search through the created lists for values equal to or greater than the given value and be added to 'string'. in the text file the first column are all letters and the second are all numbers. Is it possible to have the number column become an int?
[This is what the data looks like]
[1]: https://i.stack.imgur.com/VM3aJ.png
Thank you in advance :)
If you want the second column to be an int, you don't want to be returning the data as a single string; a list of (str, int) tuples would allow you to keep track of both values with their correct types.
I think this is closer to what you're aiming for:
from typing import List, Tuple
def read_values_with_minimum(
path: str,
n: int
) -> List[Tuple[str, int]]:
with open(path) as f:
return [
(s, int(v))
for s, v in (
line.strip().split()
for line in f.readlines()
)
if int(v) >= n
]
if __name__ == '__main__':
sf = int(input('pick a number between 1-5: '))
assert 1 <= sf <= 5
print("\n".join(
map(str, read_values_with_minimum("dna.txt", sf))
))
I have a coding assignment to input row and column length, and create a power table. THe example below is for 5 rows, 5 columns.
The code I have so far prints the correct number of rows and columns, but I haven't been able to get the calculations to work. It just shows a table of 1's, five by five.
rows = int(input("Enter a number of rows: "))
cols = int(input("Enter a number of columns: "))
x = 1
y = 1
z = 1
line = ""
while x <= cols :
line = line + format(y**cols, "4d")
x = x + 1
while z <= rows :
print(line)
z = z + 1
The basic problem is that you need to nest your loops. Your second problem is that you never change y. What you do at the moment is to compute the power sequence for 1 into five different lines -- and then you print that last line only five times. Try two changes:
Compute a line, then print it immediately. Then you go to the next line.
Use the correct variable.
After changes:
while z <= rows:
while x <= cols:
line = line + format(x**cols, "4d") # Note the variable change
x = x + 1
print(line)
z = z + 1
Also, look up the for statement, as this will simplify things. After that, look up list comprehension for even more compression.
Here is a way to do it that preserves padding no matter what:
def grid(rows, cols, padding):
max_num_len = len(str(rows**cols))
return '\n'.join([
''.join(['{{:>{}}}'.format(max_num_len+padding).format((row+1)**(col+1))
for col in range(cols)])
for row in range(rows)
])
print(grid(5, 5, 3))
Instead, try creating a 2D array in Python such as a 2D list.
Matrix = [[0 for x in range(5)] for y in range(5)]
for i in range(5):
for j in range(5):
Matrix[i][j]=j^i
Then, print the data you need using nested for loops.
for i in range (5):
for j in range(5):
print(Matrix[j][i])
I am trying to write a program that tallies the values in a file. For example, I am given a file with numbers like this
2222 (First line)
4444 (Second line)
1111 (Third line)
My program takes in the name of an input file (E.G. File.txt), and the column of numbers to tally. So for example, if my file.txt contains the number above and i need the sum of column 2, my function should be able to print out 7(2+4+1)
t1 = open(argv[1], "r")
number = argv[2]
k = 0
while True:
n = int(number)
t = t1.readline()
z = list(t)
if t == "":
break
k += float(z[n])
t1.close()
print k
This code works for the first column when I set it to 0, but it doesn't return a consistent result when I set it to 1 even though they should be the same answer.
Any thoughts?
A somewhat uglier implementation that demonstrates the cool-factor of zip:
def sum_col(filename, colnum):
with open(filename) as inf:
columns = zip(*[line.strip() for line in inf])
return sum([int(num) for num in list(columns)[colnum]])
zip(*iterable) flips from row-wise to columnwise, so:
iterable = ['aaa','bbb','ccc','ddd']
zip(*iterable) == ['abcd','abcd','abcd'] # kind of...
zip objects aren't subscriptable, so we need to cast as list before we subscript it (doing [colnum]). Alternatively we could do:
...
for _ in range(colnum-1):
next(columns) # skip the columns we don't need
return sum([int(num) for num in next(columns)])
Or just calculate all the sums and grab the sum that we need
...
col_sums = [sum(int(num) for num in column) for column in columns]
return col_sums[colnum]
Scenario, a two-dimensional list with any number of rows and columns, and the program returns a list of the row and column indices of the maximum value in the list. Example
print max_position([[2,4],[6,0],[2,6]])
list visualised:
2,6,2
4,0,6
result be [(1,0),(2,1)]
Now, how can I allow the user to enter any rows or columns of two-dimensional list to work for my code?
The code:
def max_position(list2D):
if not list2D:
return []
else:
maxi = list2D[0][0]
pos = [] #initialise with no position
for row in range(len(list2D)):
for col in range(len(list2D[row])):
if (list2D[row][col] == maxi):
if (row,col) != (0,0):
pos.append((row,col))
elif (list2D[row][col] > maxi): # new maximum found
pos = [(row,col)]
maxi = list2D[row][col]
return pos
import ast
data = raw_input("Enter your 2D array in the form [[], []]:")
x = ast.literal_eval(data)
# in
[[1,2],[3,4],[5,6]]
# out
x
[[1, 2], [3, 4], [5, 6]]
type(x)
<type 'list'>
This does not do much in the way of error handling, they must enter a syntactically correct 2D array, but it'll do the trick.
How about something like this. This would let you enter in one line at a time each sublist and add it to the overall list.
mylist = []
done = False
while not done:
line = raw_input()
if line != '':
mylist += [line.split(',')]
else:
done = True
print mylist
print "Enter space seperated values, or leave blank to finish"
print list(iter(lambda : map(int,raw_input().split()),[]))
is a fun way to do it :P
of coarse it like the other answers does not actually locate the indices in the resulting array
Here's the jist of what I'm trying to accomplish. I have a .txt file(dict.txt) which contain a ton of words. My task is count the frequency of each letter in the .txt file and put it in a list, convert each element into a percentage (divide ea element by 100), then use that list as my y_axis for my bar plot.
So far I've created a dictionary which contains each letter of alphabet as the key and the value equals the total amount of times that letter appears in the .txt file. Where I'm stuck is getting each value to divide by 100, then place that new number into a list where I can use as my y-axis for my plot. the x-axis are the letters themselves.
Here is the code I already wrote:
letter_dict = {}
word_list = []
filename = raw_input('Enter filename: ')
new_file = open(filename).readlines()
for i in new_file:
word = i.strip().lower()
word_list += list(word)
for letter in word_list:
if letter in letter_dict:
letter_dict[letter] += 1
else:
letter_dict[letter] = 1
x_axis = []
y_axis = []
summ= 0
for i in letter_dict.values(): #sum of all values in list
summ += i
value_list = list(letter_dict.values())
for k in letter_dict:
x_axis += [k]
print summ
y_axis = []
num_avg = []
for i in value_list:
y_axis += [int(i) / summ]
create_plot(x_axis, y_axis, filename) #this is for my "plot" function
whenever I for loop (i in value_list) then divide ea element by the sum, the printed list returns as [0,0,0,0,0,0,0,0,0,0,0,0,0,0]. I'm stumped.
The problem can be here:
y_axis += [int(i) / summ]
Dividing two integers resturns integer, here you get rounded the real result out.
As soon as one of the numbers is e.g. float, you will get float result.
y_axis += [int(i) / float(summ)]
The reason they return as 0 is because Python uses integer division. Use float to get more intuitive results.
In [1]: 1/5
Out[1]: 0
In [2]: float(1)/5
Out[2]: 0.2
Here is a rewritten version:
# Assumes Python 2.7
from collections import Counter
import matplotlib.pyplot as plt
from string import ascii_lowercase
def get_file():
fname = raw_input("Enter the file name: ")
with open(fname) as inf:
return inf.read()
def count_letters(s):
chars = Counter(s.lower())
return {ch:chars[ch] for ch in ascii_lowercase}
def plot_letters(count):
total = sum(count.values())
xs = range(len(ascii_lowercase))
ys = [count[ch] * 100. / total for ch in ascii_lowercase]
plt.bar(xs, ys)
plt.xticks([x+0.5 for x in xs], ascii_lowercase)
plt.show()
def main():
letters = get_file()
count = count_letters(letters)
plot_letters(count)
main()
which produces something like: