Python looping and appending arrays - python

I'm creating an application to test how many 'steps' it takes for a number to reach 1 using the colatz conjecture. Here is the code:
import sys
import csv
def findSteps(mode):
count = 0
while mode != 1:
count = count + 1
if mode%2 == 0:
mode = mode/2
else:
mode = (3*mode)+1
return count
numbers = []
counts = []
for n in range(1, 100):
important = findSteps(n)
numbers[n] = n
counts[n] = important
with open('colatz conjecture table.csv', 'wb') as csvfile:
myWriter = csv.writer(csvfile, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL)
myWriter.writerow(numbers)
myWriter.writerow(counts)
Unfortunately, whenever I run it, it gives me a "Index Error: List Assignment out of range."

In addition of the list.append() variant, you may also use
numbers = range(1, 100)
counts = [findSteps(n) for n in numbers]
Or, if you like to keep it functional
numbers = range(1, 100)
counts = map(findSteps, numbers)

Both numbers and counts have a type of list, based on how you defined them in your code. So you can use the method of append to add the data to both of them. Just remember that the indexes are zero-based.
Moreover, I agree with #Evert's comment it looks like a dictionary object is better suited for your needs.

Related

Problem with reading data from file in Python

EDIT:
Thanks for fixing it! Unfortunatelly, it messed up the logic. I'll explain what this program does. It's a solution to a task about playing cards trick. There are N cards on the table. First and Second are numbers on the front and back of the cards. The trick can only be done, if the visible numbers are in non-decreasing order. Someone from audience can come and swap places of cards. M represents how many cards will be swapped places. A and B represent which cards will be swapped. Magician can flip any number of cards to see the other side. The program must tell, if the magician can do the trick.
from collections import namedtuple
Pair = namedtuple("Pair", ["first", "second"])
pairs = []
with open('data.txt', 'r') as data, open('results.txt', 'w') as results:
n = data.readline()
n = int(n)
for _ in range(n):
first, second = (int(x) for x in data.readline().split(':'))
first, second = sorted((first, second))
pairs.append(Pair(first, second)) # add to the list by appending
m = data.readline()
m = int(m)
for _ in range(m):
a, b = (int(x) for x in data.readline().split('-'))
a -= 1
b -= 1
temp = pairs[a]
pairs[a] = pairs[b]
pairs[b] = temp
p = -1e-9
ok = True
for k in range(0, n):
if pairs[k].first >= p:
p = pairs[k].first
elif pairs[k].second >= p:
p = pairs[k].second
else:
ok = False
break
if ok:
results.write("YES\n")
else:
results.write("NO\n")
data:
4
2:5
3:4
6:3
2:7
2
3-4
1-3
results:
YES
YES
YES
YES
YES
YES
YES
What should be in results:
NO
YES
The code is full of bugs: you should write and test it incrementally instead of all at once. It seems that you started using readlines (which is a good way of managing this kind of work) but you kept the rest of the code in a reading one by one style. If you used readlines, the line for i, line in enumerate(data): should be changed to for i, line in enumerate(lines):.
Anyway, here is a corrected version with some explanation. I hope I did not mess with the logic.
from collections import namedtuple
Pair = namedtuple("Pair", ["first", "second"])
# The following line created a huge list of "Pairs" types, not instances
# pairs = [Pair] * (2*200*1000+1)
pairs = []
with open('data.txt', 'r') as data, open('results.txt', 'w') as results:
n = data.readline()
n = int(n)
# removing the reading of all data...
# lines = data.readlines()
# m = lines[n]
# removed bad for: for i, line in enumerate(data):
for _ in range(n): # you don't need the index
first, second = (int(x) for x in data.readline().split(':'))
# removed unnecessary recasting to int
# first = int(first)
# second = int(second)
# changed the swapping to a more elegant way
first, second = sorted((first, second))
pairs.append(Pair(first, second)) # we add to the list by appending
# removed unnecessary for: once you read all the first and seconds,
# you reached M
m = data.readline()
m = int(m)
# you don't need the index... indeed you don't need to count (you can read
# to the end of file, unless it is malformed)
for _ in range(m):
a, b = (int(x) for x in data.readline().split('-'))
# removed unnecessary recasting to int
# a = int(a)
# b = int(b)
a -= 1
b -= 1
temp = pairs[a]
pairs[a] = pairs[b]
pairs[b] = temp
p = -1e-9
ok = True
for k in range(0, n):
if pairs[k].first >= p:
p = pairs[k].first
elif pairs[k].second >= p:
p = pairs[k].second
else:
ok = False
break
if ok:
results.write("YES\n")
else:
results.write("NO\n")
Response previous to edition
range(1, 1) is empty, so this part of the code:
for i in range (1, 1):
n = data.readline()
n = int(n)
does not define n, at when execution gets to line 12 you get an error.
You can remove the for statement, changing those three lines to:
n = data.readline()
n = int(n)

Fewest number of changes to an imperfect melody to make it perfect

I have just started learning how to code 'competitively' in competitions and came across this problem:
A 'perfect' melody is one that has the same 3 numbers repeating over, for example:
123123123
And so a 'non-perfect' one would be for example: 123122121
Now the question asks how many numbers need to be changed in an imperfect melody to make it 'perfect'. Below is an example: (in the first row of the input file , the first one is the amount of notes and the second one is the max value each note can take and then the rest of the numbers are the notes in order)
Example:
Example
I have produced a solution that doesn't solve most of the test cases and I don't see why. My code is below:
#!/usr/bin/env python
import sys
sys.setrecursionlimit(1000000000)
# N is the number of notes.
N = None
# K is the largest number which could be a note.
K = None
# S contains the sequence of notes forming the song.
S = [None for x in range(100005)]
answer = None
# Open the input and output files.
input_file = open("melodyin.txt", "r")
output_file = open("melodyout.txt", "w")
# Read the value of N and K.
input_line = input_file.readline().strip()
N, K = map(int, input_line.split())
# Read each note in the song.
for i in range(0, N):
S[i] = int(input_file.readline().strip())
notes_list = []
for i in range(0, N):
notes_list.append(S[i])
count = 0
sep = []
for i in range(N//3):
sep.append([notes_list[count], notes_list[count+1], notes_list[count+2]])
count += 3
errors = 0
for i in range(len(sep)-1):
if sep[0][0] != sep[i+1][0]:
errors += 1
if sep[0][1] != sep[i+1][1]:
errors += 1
if sep[0][2] != sep[i+1][2]:
errors += 1
else:
pass
# Write the answer to the output file.
output_file.write("%d\n" % (errors))
# Finally, close the input/output files.
input_file.close()
output_file.close()
additionally these are the constraints:
• 3≤N≤99999.
• N is a multiple of three. • 1≤K≤100000.
• 1≤Si ≤K,for all i

how to create a list and then print it in ascending order

def list():
list_name = []
list_name_second = []
with open('CoinCount.txt', 'r', encoding='utf-8') as csvfile:
num_lines = 0
for line in csvfile:
num_lines = num_lines + 1
i = 0
while i < num_lines:
for x in volunteers[i].name:
if x not in list_name: # l
f = 0
while f < num_lines:
addition = []
if volunteers[f].true_count == "Y":
addition.append(1)
else:
addition.append(0)
f = f + 1
if f == num_lines:
decimal = sum(addition) / len(addition)
d = decimal * 100
percentage = float("{0:.2f}".format(d))
list_name_second.append({'Name': x , 'percentage': str(percentage)})
list_name.append(x)
i = i + 1
if i == num_lines:
def sort_percentages(list_name_second):
return list_name_second.get('percentage')
print(list_name_second, end='\n\n')
above is a segment of my code, it essentially means:
If the string in nth line of names hasn't been listed already, find the percentage of accurate coins counted and then add that all to a list, then print that list.
the issue is that when I output this, the program is stuck on a while loop continuously on addition.append(1), I'm not sure why so please can you (using the code displayed) let me know how to update the code to make it run as intended, also if it helps, the first two lines of code within the txt file read:
Abena,5p,325.00,Y
Malcolm,1p,3356.00,N
this doesn't matter much but just incase you need it, I suspect that the reason it is stuck looping addition.append(1) is because the first line has a "Y" as its true_count

File data binding with column names

I have files with hundreds and thousands rows of data but they are without any column.
I am trying to go to every file and make them row by row and store them in list after that I want to assign values by columns. But here I am confused what to do because values are around 60 in every row and some extra columns with value assigned and they should be added in every row.
Code so for:
import re
import glob
filenames = glob.glob("/home/ashfaque/Desktop/filetocsvsample/inputfiles/*.txt")
columns = []
with open("/home/ashfaque/Downloads/coulmn names.txt",encoding = "ISO-8859-1") as f:
file_data = f.read()
lines = file_data.splitlines()
for l in lines:
columns.append(l.rstrip())
total = {}
for name in filenames:
modified_data = []
with open(name,encoding = "ISO-8859-1") as f:
file_data = f.read()
lines = file_data.splitlines()
for l in lines:
if len(l) >= 1:
modified_data.append(re.split(': |,',l))
rows = []
i = len(modified_data)
x = 0
while i > 60:
r = lines[x:x+59]
x = x + 60
i = i - 60
rows.append(r)
z = len(modified_data)
while z >= 60:
z = z - 60
if z > 1:
last_columns = modified_data[-z:]
x = []
for l in last_columns:
if len(l) > 1:
del l[0]
x.append(l)
elif len(l) == 1:
x.append(l)
for row in rows:
for vl in x:
row.append(vl)
for r in rows:
for i in range(0,len(r)):
if len(r) >= 60:
total.setdefault(columns[i],[]).append(r[i])
In other script I have separated both row with 60 values and last 5 to 15 columns which should be added with row are separate but again I am confused how to bind all the data.
Data Should look like this after binding.
outputdata.xlsx
Data Input file:
inputdata.txt
What Am I missing here? any tool ?
I believe that your issue can be resolved by taking the input file and turning it into a CSV file which you can then import into whatever program you like.
I wrote a small generator that would read a file a line at a time and return a row after a certain number of lines, in this case 60. In that generator, you can make whatever modifications to the data as you need.
Then with each generated row, I write it directly to the csv. This should keep the memory requirements for this process pretty low.
I didn't understand what you were doing with the regex split, but it would be simple enough to add it to the generator.
import csv
OUTPUT_FILE = "/home/ashfaque/Desktop/File handling/outputfile.csv"
INPUT_FILE = "/home/ashfaque/Desktop/File handling/inputfile.txt"
# This is a generator that will pull only num number of items into
# memory at a time, before it yields the row.
def get_rows(path, num):
row = []
with open(path, "r", encoding="ISO-8859-1") as f:
for n, l in enumerate(f):
# apply whatever transformations that you need to here.
row.append(l.rstrip())
if (n + 1) % num == 0:
# if rows need padding then do it here.
yield row
row = []
with open(OUTPUT_FILE, "w") as output:
csv_writer = csv.writer(output)
for r in get_rows(INPUT_FILE, 60):
csv_writer.writerow(r)

Finding average in .txt file python

i need to print out average height from a .txt file. How do I write it in an easy way? The .txt file has these numbers:
12
14
59
48
45
12
47
65
152
this is what i've got so far:
import math
text = open(r'stuff.txt').read()
data = []
with open(r'stuff.txt') as f:
for line in f:
fields = line.split()
rowdata = map(float, fields)
data.extend(rowdata)
biggest = min(data)
smallest = max(data)
print(biggest - smallest)
To compute the average of some numbers, you should sum them up and then divide by the number of numbers:
data = []
with open(r'stuff.txt') as f:
for line in f:
fields = line.split()
rowdata = map(float, fields)
data.extend(rowdata)
print(sum(data)/len(data))
# import math -- you don't need this
# text = open(r'stuff.txt').read() not needed.
# data = [] not needed
with open(r'stuff.txt') as f:
data = [float(line.rstrip()) for line in f]
biggest = min(data)
smallest = max(data)
print(biggest - smallest)
print(sum(data)/len(data))
data = [float(ln.rstrip()) for ln in f.readlines()] # Within 'with' statement.
mean_average = float(sum(data))/len(data) if len(data) > 0 else float('nan')
That is the way to calculate the mean average, if that is what you meant. Sadly, math does not have a function for this. FYI, the mean_average line is modified in order to avoid the ZeroDivisionError bug that would occur if the list had a length of 0- just in case.
Array average can be computed like this:
print(sum(data) / len(data))
A simple program for finding the average would be the following (if I understand well, your file has one value in each line, if so, it has to be similar to this, else it has to change accordingly):
import sys
f = open('stuff.txt', 'rU')
lines = f.readlines()
f.close()
size = len(lines)
sum=0
for line in lines:
sum = sum + float(line.rstrip())
avg = sum / float(size)
print avg,
Not the best that can be in python but it's quite straight forward I think...
A full, almost-loopless solution combining elements of other answers here:
with open('stuff.txt','r') as f:
data = [float(line.rstrip()) for line in f.readlines()]
f.close()
mean = float(sum(data))/len(data) if len(data) > 0 else float('nan')
and you don't need to prepend, append, enclose or import anything else.

Categories

Resources