Creating a calculation table from text file - python

88 90 94 98 100 110 120
75 77 80 86 94 103 113
80 83 85 94 111 111 121
68 71 76 85 96 122 125
77 84 91 102 105 112 119
81 85 90 96 102 109 134
Hi i am very new to computer programming in general and I need some help with my current project. I need to read numbers from a text file into a table and calculate the averages and max.This is what I currently have.
def main():
intro()
#sets variables
n1=[]
n2=[]
n3=[]
n4=[]
n5=[]
n6=[]
n7=[]
numlines = 0
filename = input("Enter the name of the data file: ")
print() #turnin
infile = open(filename,"r")
for line in infile:
#splits the lines
data = line.split()
#takes vertical lines individually and converts them to integers
n1.append(int(data[0]))
n2.append(int(data[1]))
n3.append(int(data[2]))
n4.append(int(data[3]))
n5.append(int(data[4]))
n6.append(int(data[5]))
n7.append(int(data[6]))
datalist = n1,n2,n3,n4,n5,n6
#calculates the average speeds
n1av = (sum(n1))/len(n1)
n2av = (sum(n2))/len(n2)
n3av = (sum(n3))/len(n3)
n4av = (sum(n4))/len(n4)
n5av = (sum(n5))/len(n5)
n6av = (sum(n6))/len(n6)
n7av = (sum(n7))/len(n7)
#calculates the max speeds
n1max = max(n1)
n2max = max(n2)
n3max = max(n3)
n4max = max(n4)
n5max = max(n5)
n6max = max(n6)
n7max = max(n7)
#Calculates the average of the average speeds
Avgav = (n1av + n2av + n3av + n4av + n5av + n6av + n7av) / 7
#Calculates the average of the average max
Avmax = (n1max + n2max + n3max + n4max + n5max + n6max + n7max) / 7
#creates table
print(aver_speed)
print()
print(" "* 27, "Speed (MPH)")
print(" "*3,"Car :", "{:6}".format(30),"{:6}".format(40),"{:6}".format(50)
,"{:6}".format(60),"{:6}".format(70),"{:6}".format(80),
"{:6}".format(90)," :","{:14}".format ("Average Noise"))
print("-"*77)
for i in range(0,len(datalist)):
print("{:6}".format(int("1")+1)," "*2,":", "{:6}".format (n1[i]), "{:6}".format (n2[i]), "{:6}".format (n3[i]),
"{:6}".format (n4[i]),"{:6}".format (n5[i]),"{:6}".format (n6[i]),"{:6}".format (n7[i])," :", )
print("-"*77)
print(" ","Average","{:1}".format(":"), "{:8.1f}".format(n1av),"{:6.1f}".format(n2av),
"{:6.1f}".format(n3av),"{:6.1f}".format(n4av),"{:6.1f}".format(n5av),"{:6.1f}".format(n6av),
"{:6.1f}".format(n7av), "{:9.1f}".format(Avgav))
print()
print(" ","Maximum","{:1}".format(":"), "{:6}".format(n1max), "{:6}".format(n2max), "{:6}".format(n3max), "{:6}".format(n4max)
, "{:6}".format(n5max), "{:6}".format(n6max), "{:6}".format(n7max),"{:11.1f}".format(Avmax))
Any help would be appreciated.
Now that i have updated my code my table looks like this:
Car : 30 40 50 60 70 80 90 : Average Noise
2 : 88 90 94 98 100 110 120 :
2 : 75 77 80 86 94 103 113 :
2 : 80 83 85 94 111 111 121 :
2 : 68 71 76 85 96 122 125 :
2 : 77 84 91 102 105 112 119 :
2 : 81 85 90 96 102 109 134 :
Average : 78.2 81.7 86.0 93.5 101.3 111.2 122.0 96.3
Maximum : 88 90 94 102 111 122 134 105.9
I've been trying to figure out the calculations for average noise and how to list the cars 1 through 6. I was unable to fi

You have a lot of code now. You can do this easier. If you want calculate by strings:
with open(filename, 'r') as f:
for line in f.readlines():
list_of_speed = map(int, line.split())
max_speed = max(list_of_speed)
aver_speed = float(sum(list_of_speed))/len(list_of_speed)
If by column:
with open(filename, 'r') as f:
l = map(lambda x: map(int, x.split()), f.readlines())
for n in range(len(l[0])):
list_of_speed = [value[n] for value in l]
max_speed = max(list_of_speed)
aver_speed = float(sum(list_of_speed))/len(list_of_speed)

You can use sum() function on a list and len() function gives the number of elements in the list. So for average calculation you can simply do sum(n1)/float(len(n1)).
Try to use some dynamic way of keeping track of read data or calculate sum and avg on the fly and keep track of that data. Not to discourage you but using six lists doesn't look so elegant. Hope something similar to this might work:
from pprint import pprint
def main():
# intro()
filename = input("Enter the name of the data file:")
infile = open(filename,"r")
n = {} # a dictionary
for line in infile:
# apply typecasting on each element
data = map(int, line.split())
# add speeds into to a dictionary of lists
# supports any number of data sets
for i,d in enumerate(data):
if i+1 in n:
n[i+1].append(d)
else:
n[i+1] = [d]
pprint (n)
# do whatever you want with the dictionary
for d in n:
print ("-" * 10)
print (d)
print (sum(n[d]))
print (sum(n[d])/float(len(n[d])))
main()
For printing purposes you may want to use some thing like https://pypi.python.org/pypi/PTable

Related

Python, trying to calculate RSI but I am getting unusually high numbers

I am trying to calculate the RSI formula in python. I am getting the closing price data from the AlphaVantage TimeSeries API.
def rsi(data,period):
length = len(data) - 1
current_price = 0
previous_price = 0
avg_up = 0
avg_down = 0
for i in range(length-period,length):
current_price = data[i]
if current_price > previous_price:
avg_up += current_price - previous_price
else:
avg_down += previous_price - current_price
previous_price = data[i]
# Calculate average gain and loss
avg_up = avg_up/period
avg_down = avg_down/period
# Calculate relative strength
rs = avg_up/avg_down
# Calculate rsi
rsi = 100 - (100/(1+rs))
return rsi
print(rsi(data=closing_price,period=14))
In this case, this will output a really high number along the lines of RSI: 99.824. But according to TradingView, the current RSI is actually 62.68.
Any feedback on what I am doing wrong would be very much appreciated!
Here is some data, it is 100 mintues of AAPL data
0
0 118.3900
1 118.4200
2 118.3500
3 118.3000
4 118.2800
5 118.4000
6 118.3400
7 118.4500
8 118.3900
9 118.4100
10 118.4700
11 118.4000
12 118.4000
13 118.3400
14 118.4100
15 118.2850
16 118.2900
17 118.1700
18 118.2600
19 118.2800
20 118.2600
21 118.2400
22 118.2950
23 118.2800
24 118.2900
25 118.2850
26 118.3000
27 118.2150
28 118.2300
29 118.1450
30 118.1200
31 118.0800
32 118.1300
33 118.1100
34 118.1300
35 118.2300
36 118.1000
37 118.1900
38 118.2800
39 118.2400
40 118.2300
41 118.3300
42 118.3200
43 118.3500
44 118.3600
45 118.3650
46 118.3800
47 118.4500
48 118.5000
49 118.5100
50 118.5400
51 118.5100
52 118.5063
53 118.5200
54 118.5400
55 118.4700
56 118.4700
57 118.4300
58 118.4400
59 118.4300
60 118.3800
61 118.4000
62 118.3600
63 118.3700
64 118.3400
65 118.3200
66 118.3000
67 118.3210
68 118.3714
69 118.4000
70 118.4100
71 118.3500
72 118.3300
73 118.3200
74 118.3250
75 118.3200
76 118.3900
77 118.5000
78 118.4800
79 118.5300
80 118.5300
81 118.4800
82 118.5000
83 118.4400
84 118.5400
85 118.5550
86 118.5200
87 118.4600
88 118.4500
89 118.4400
90 118.4300
91 118.4019
92 118.4400
93 118.4400
94 118.4100
95 118.4000
96 118.4400
97 118.4400
98 118.4600
99 118.5050
I've managed to compute 59.4 with the code below, which is close to what you are looking to. Here is what I've changed:
_ averages are divided by n_up and n_down counters, and not by period.
_ previous and current prices were removed to directly access to actual data[i] and previous data[i-1] prices.
Note that the code has to be check with other data.
close_AAPL = [118.4200, 118.3500, 118.3000, 118.2800, 118.4000,
118.3400, 118.4500, 118.3900, 118.4100, 118.4700,
118.4000, 118.4000, 118.3400, 118.4100, 118.2850,
118.2900, 118.1700, 118.2600, 118.2800, 118.2600,
118.2400, 118.2950, 118.2800, 118.2900, 118.2850,
118.3000, 118.2150, 118.2300, 118.1450, 118.1200,
118.0800, 118.1300, 118.1100, 118.1300, 118.2300,
118.1000, 118.1900, 118.2800, 118.2400, 118.2300,
118.3300, 118.3200, 118.3500, 118.3600, 118.3650,
118.3800, 118.4500, 118.5000, 118.5100, 118.5400,
118.5100, 118.5063, 118.5200, 118.5400, 118.4700,
118.4700, 118.4300, 118.4400, 118.4300, 118.3800,
118.4000, 118.3600, 118.3700, 118.3400, 118.3200,
118.3000, 118.3210, 118.3714, 118.4000, 118.4100,
118.3500, 118.3300, 118.3200, 118.3250, 118.3200,
118.3900, 118.5000, 118.4800, 118.5300, 118.5300,
118.4800, 118.5000, 118.4400, 118.5400, 118.5550,
118.5200, 118.4600, 118.4500, 118.4400, 118.4300,
118.4019, 118.4400, 118.4400, 118.4100, 118.4000,
118.4400, 118.4400, 118.4600, 118.5050]
def rsi(data,period):
length = len(data) - 1
current_price = 0
previous_price = 0
avg_up = 0
n_up = 0
avg_down = 0
n_down = 0
for i in range(length-period,length):
if data[i] > data[i-1]:
avg_up += data[i] - data[i-1]
n_up += 1
else:
avg_down += data[i-1] - data[i]
n_down += 1
# Calculate average gain and loss
avg_up = avg_up/n_up
avg_down = avg_down/n_down
# Calculate relative strength
rs = avg_up/avg_down
# Calculate rsi
return 100. - 100./(1+rs)
print(rsi(data=close_AAPL, period=14))

Rot18, encrypt and decrypt (python, Sublime Text)

I am looking for a plugin that can encrypt/decrypt text using rot18 in Sublime Text v3.2.2.
I tried this tutorial (only rot13) but it doesn’t work for me: https://www.sublimetext.com/docs/plugin-examples
I tried a lot of plugins and the only one that works fine is:
(unfortunately it is rot47)
import sublime
import sublime_plugin
class Rot47Command(sublime_plugin.TextCommand):
def run(self, edit):
for region in self.view.sel():
if not region.empty():
s = self.view.substr(region)
s = ''.join(chr(33 + ((ord(ch) + 14) % 94)) for ch in s)
self.view.replace(edit, region, s)
Does anyone have any functional plugin on rot18, please?
You can adapt your code. Here is how rot_N works:
This is the ASCII-Range up to 127:
a = 32
for k in range(0,16):
print(a+k, chr(a+k), " ", a+16+k, chr(a+16+k), " ", a+32+k, chr(a+32+k), " ",
a+48+k, chr(a+48+k), " ", a+64+k, chr(a+64+k), " ", a+80+k, chr(a+80+k))
# 32 48 0 64 # 80 P 96 ` 112 p
# 33 ! 49 1 65 A 81 Q 97 a 113 q
# 34 " 50 2 66 B 82 R 98 b 114 r
# 35 # 51 3 67 C 83 S 99 c 115 s
# 36 $ 52 4 68 D 84 T 100 d 116 t
# 37 % 53 5 69 E 85 U 101 e 117 u
# 38 & 54 6 70 F 86 V 102 f 118 v
# 39 ' 55 7 71 G 87 W 103 g 119 w
# 40 ( 56 8 72 H 88 X 104 h 120 x
# 41 ) 57 9 73 I 89 Y 105 i 121 y
# 42 * 58 : 74 J 90 Z 106 j 122 z
# 43 + 59 ; 75 K 91 [ 107 k 123 {
# 44 , 60 < 76 L 92 \ 108 l 124 |
# 45 - 61 = 77 M 93 ] 109 m 125 }
# 46 . 62 > 78 N 94 ^ 110 n 126 ~
# 47 / 63 ? 79 O 95 _ 111 o 127
ROT n means you take the chr(ord(l)+n)'s letter instead. You need to be carefull when wrapping around.
For calculation of rot_N the basic formular is:
def rot_N(n,letter):
return chr( (ord(letter)-32+n) % (128-32) + 32) # 128-32 = 96
You can test it with:
k="Hello Zzzzz"
print( ''.join(rot_N(18, l) for l in k)) # schould give you a tranlation
print( ''.join(rot_N(0, l) for l in k)) # should give the exact text
and test the inverse with:
k_inverse ="Zw~~!2l,,,,"
print( ''.join(rot_N(-18, l) for l in k_inverse)) # use -18 here
print( ''.join(rot_N(0, l) for l in k_inverse))
If you replace
s = ''.join(chr(33 + ((ord(ch) + 14) % 94)) for ch in s)
with
s = ''.join(rot_N(18, ch) for ch in s))
you should be fine.
You do not specify, but I assume you are using ROT-18 on the character set 0..9, A..Z which is 36 characters. 36/2 = 18, hence ROT-18.
ROT-13 works on the 26 alphabetic characters: 26/2 = 13. You want to adapt that to ROT-18.
The major difference is that the alphabetic characters are continuous in the ASCII character set, and that assumption is built into the code you are copying from. The same is true for ROT-47; the ASCII characters used are continuous. With ROT-18, the digits 0..9 and the alphabetic characters, A..Z are not continuous in ASCII. There is a gap between them from : (#58) to # (#64). ASCII codes in that region are neither digits nor letters.
One solution is to set up your own array, not in the ASCII order, where the two are continuous: [0, 1, ... 9, A, B, ... Z]. Write your program to work on that array.
Alternatively you can work with the ASCII codes, treating codes from #58 to #64 specially to make the shift come out right.
The first option is probably easier, and the code will be more similar to the ROT-13 example. The main difference will be replacing the ord() function, which returns the ASCII code, with an equivalent function giving the position in your array.

Print Dictionary with commas separating values

import csv
import output
fill = input("Enter File name:")
f = open(fill)
csv_f = csv.reader(f)
m = open('data.csv', "w")
dict_out = {}
for row in csv_f:
if row[1] in dict_out:
dict_out[row[1]] += row[3]
else:
dict_out[row[1]] = row[3]
for title, value in dict_out.items():
m.write('{},'.format(title))
m.write ('{} \n'.format(value))
m.close()
Prints my csv as
Title,Detail
Siding, 50 63 22 68 138 47 123 107 107 93 117
Asphalt, 49 8 72 19 125 95 33 83 123 144
Rail, 82 98 89 62 58 66 24 77 120 93
Grinding, 127 47 20 66 29 137 33 145 3 98
Concrete, 130 75 12 88 22 137 114 88 143 16
I would like to put a comma in between the numbers. I have tried m.write(',') after m.write('{} \n'.format(value)) but it only adds it after the last one. How can i format it so it will output as
Title,Detail
Siding, 50,63,22,68,138,47,123,107,107,93,117
Asphalt, 49,8,72,191,25,95,33,83,123,144
Rail, 82,98,89,62,58,66,24,77,120,93
Grinding, 127,47,20,66,29,137,33,145,3,98
Concrete, 130,75,12,88,22,137,114,88,143,16
not the best way but you can:
for title, value in dict_out.items():
m.write('{},'.format(title))
m.write ('{} \n'.format(value.replace(' ', ',')))
but you should definetly use csv writter,
import csv
import output
fill = input("Enter File name:")
f = open(fill)
csv_f = csv.reader(f)
c = open('data.csv', "w")
m = csv.writer(c)
dict_out = {}
for row in csv_f:
if row[1] in dict_out:
dict_out[row[1]].append(row[3])
else:
dict_out[row[1]] = [row[3]]
for title, value in dict_out.items():
m.writerow([title] + value)
c.close()
If value is a string then you need to use value.split(). If it is already a list then you don't need to use the split method.
with open('data.csv', "w") as m:
for title, value in dict_out.items():
m.write(title + "," + ",".join(value.split()) + "\n")

Word is not defined

In this program, I am trying to write the index out to a text file named "index.txt", along with printing it out. However, whenever i run the program, I get an error saying "words" is not defined, and my index.txt file only prints out word/tLine Numbers.
Code:
from string import punctuation
def makeIndex(filename):
wordIndex = {}
with open(filename) as f:
lineNum = 1
for line in f:
words = line.lower().split()
for word in words:
for char in punctuation:
word = word.replace(char, '')
if word.isalpha():
if word in wordIndex.keys():
if lineNum not in wordIndex[word]:
wordIndex[word].append(lineNum)
else:
wordIndex[word] = [lineNum]
lineNum += 1
return wordIndex
def output(wordIndex):
print("Word\tLine Numbers")
for key in sorted(wordIndex.keys()):
print(key, '\t', end=" ")
for lineNum in wordIndex[key]:
print(lineNum, end=" ")
print()
def main():
filename = input("What is the file name to be indexed?")
index = makeIndex(filename)
output(index)
with open('index.txt', 'w') as writefile:
writefile.write("Word/tLine Numbers")
print('t', end= "")
for index in range(len(word)):
print(word[index])
writefile.write(word[index] + '/n')
main()
Output:
What is the file name to be indexed?test.txt
Word Line Numbers
a 8 12 38 70 78
all 85 101
also 91
an 34 96
anagrams 93 104
as 84
ask 28
blocks 4
called 61
create 69
different 59
difficulties 47
each 74
employed 65
figure 32
file 9
find 100
finds 92
following 22
for 18 73
given 37
has 80
have 56
here 66
in 7 48
interesting 19
is 52 67
it 103
its 42 87
jumble 25
large 3
letters 43
long 54
many 58
new 14
of 5 16 41 45 86 102
one 44
opens 10
out 33
permutations 62 88
possibilities 17
problem 51
program 23 90
programs 20
puzzles 26
range 15
reorderings 60
same 82
scrambled 39
set 40
signature 72 83
since 94
so 57 76
solver 30
solves 24
solving 49
strategy 64
text 6
that 53 77
the 21 29 46 63 81
this 50 89
to 31 68
typing 95
unique 71
unknown 35
unscrambled 97
up 11
which 27
whole 13
will 99
with 2
word 36 75 79 98
words 55
working 1
tTraceback (most recent call last):
File "C:\Users\jp19p_000\Desktop\wordIndex(1).py", line 46, in <module>
main()
File "C:\Users\jp19p_000\Desktop\wordIndex(1).py", line 41, in main
for index in range(len(word)):
NameError: name 'word' is not defined
This is the index.txt file:
Word/tLine Numbers
from collections import defaultdict
import string
import sys
# convert to lowercase, remove all digits and punctuation
trans = str.maketrans(string.ascii_uppercase, string.ascii_lowercase, string.digits + string.punctuation)
def get_unique_words(s, trans=trans):
return set(s.translate(trans).split())
def make_index(seq, start=1):
index = defaultdict(list)
for i,s in enumerate(seq, start):
for word in get_unique_words(s):
index[word].append(i)
return index
def write_index(index, file=sys.stdout):
print("Word\tLines", file=file)
for word in sorted(index.keys()):
lines = " ".join(str(i) for i in index[word])
print("{}\t{}".format(word, lines), file=file)
def main():
fname = input("What is the name of the file to be indexed? ")
with open(fname) as inf:
index = make_index(inf)
with open("index.txt", "w") as outf:
write_index(index, outf)
if __name__=="__main__":
main()

How to delete duplicate values and write to different files?

I am trying to read a file that looks like this:
83 124 125
83 125 126
83 126 127
83 127 128
83 128 128
154 120 120
154 120 121
154 121 122
154 122 123
154 123 124
122 92 93
122 93 94
122 94 95
122 95 96
122 96 97
And write to different files every set of values. The first value (83 / 154 / 122) needs to be the text file's name. The rest of the values should be written into their correspondent file like so: 124 128
So file "83.txt" contains 124 128. The file "154.txt" contains 120 124. And the file "122.txt should contain 92 97.
How do i iterate over the above mentioned input and remove duplicate values from the first column? Then proceed into taking the minimum and maximum values that each of the first values share? and finally write each separate line into a new text file inside a certain folder?
I have tried to use:
from itertools import chain
from collections import defaultdict
from operator import itemgetter
from itertools import groupby
def final(f):
with open (f+'.txt', 'r') as fin:
lines = fin.readlines().split().strip('\n')
v1, v2, v3 = lines[0], lines[1], lines[2]
for v1, g in groupby(enumerate(diffs[v1x]), lambda (i, x): i - x):
group = map(itemgetter(1), g)
lines.itertools.chain()
lines = defaultdict(list)
print (lines),
Which is an incomplete version of what i had earlier but i can't seem to make it work like it did before. Anyway my code ended up very long and not that readable... If more details are required for this to be answered I'll provide them. I'd like to see different takes on this and not simply posting my crude code and get it tweaked by someone.
Assuming the filenames are "in order", and the other items are in order, then:
from itertools import groupby
from operator import itemgetter
from collections import deque
with open('/home/jon/testdata.txt') as fin:
lines = (line.split() for line in fin)
for k, g in groupby(lines, itemgetter(0)):
fst = next(g)
lst = next(iter(deque(g, 1)), fst)
with open(k + '.txt', 'w') as fout:
fout.write(fst[1] + ' ' + lst[2])
long_string = """ 83 124 125
83 125 126
83 126 127
83 127 128
83 128 128
154 120 120
154 120 121
154 121 122
154 122 123
154 123 124
122 92 93
122 93 94
122 94 95
122 95 96
122 96 97
"""
files = {}
for line in long_string.split("\n"):
try:
filenum, minvalue, maxvalue = line.strip().split(" ")
try:
new_min = min(files[filenum][0], minvalue)
new_max = max(files[filenum][1], maxvalue)
files[filenum] = (new_min, new_max)
except KeyError:
files[filenum] = (minvalue, maxvalue)
except ValueError:
print("There are no 3 values as excpected")
for filename, values in files.iteritems():
with open(filename + ".txt", "wb") as writer:
writer.write(values[0] + " " + values[1])

Categories

Resources