Why my program takes so long time? [closed] - python

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
I am dealing with a large txt file, there are overall 8050000 lines. A short example of the lines are:
usedfor zipper fasten_coat
usedfor zipper fasten_jacket
usedfor zipper fasten_pant
usedfor your_foot walk
atlocation camera cupboard
atlocation camera drawer
atlocation camera house
relatedto more plenty
I write a python code to read the lines, and store them as a dictionary. My code is:
dicCSK = {}
for line in finCSK:
line=line.strip('\n')
try:
r, c1, c2 = line.split(" ")
except ValueError: print line
if c1 not in dicCSK.keys():
dicCSK[c1]= []
str1 = r+" "+c2
dicCSK[c1].append(str1)
However, I ran the program for over 20 hours, it is still running. So is there any better way to store them in a dictionary? My code is too slow. Thanks.

This is a mistake: it generates a list of all keys in the dictionary and then scans over it.
if c1 not in dicCSK.keys():
dicCSK[c1]= []
Instead:
if c1 not in dicCSK:
dicCSK[c1] = []
Or instead, use a defaultdict to avoid the check.
dicCSK = collections.defaultdict(list)
for line in finCSK:
line=line.strip('\n')
try:
r, c1, c2 = line.split(" ")
except ValueError:
print line
dicCSK[c1].append(r+" "+c2)
Also, probably you also want the dicCSK[c1].append(r+" "+c2) statement under an else clause of the try/except otherwise it will execute even when there's a ValueError exception.

Related

Tips For an Intro Python Program [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Below is my first python program. I am trying idea not yet covered in class as i hate staying stagnant and want to solve issues that may arise if i were to just use the info we've learned in class. As for my question, the program works but what were be ways to condense the code, if any? Thanks!
#This is a program to provide an itemized receipt for a campsite
# CONSTANTS
ELECTRICITY=10.00 #one time electricity charge
class colors:
ERROR = "\033[91m"
END = "\033[0m"
#input validation
while True:
while True:
try:
nightly_rate=float(input("Enter the Basic Nightly Rate:$"))
except ValueError:
print(colors.ERROR +"ERROR: Please Enter the Dollar Amount"+colors.END)
else:
break
while True:
try:
number_of_nights=int(input("Enter the Number of Nights You Will Be Staying:"))
except ValueError:
print(colors.ERROR +"ERROR: Please Enter a Number"+colors.END)
else:
break
while True:
try:
campers=int(input("Enter the Number of Campers:"))
except ValueError:
print(colors.ERROR +"ERROR: Please Enter a Number"+colors.END)
else:
break
break
#processing
while True:
try:
campsite=nightly_rate*number_of_nights
tax=(ELECTRICITY*0.07)+(campsite*0.07)
ranger=(campsite+ELECTRICITY+tax)*0.15 #gratuity paid towards Ranger
total=campsite+ELECTRICITY+tax+ranger #total paid per camper
total_per=total/campers
except ZeroDivisionError: #attempt to work around ZeroDivisionError
total_per=0 #total per set to zero as the user inputed 0 for number-
break #-of campers
#Output #Cant figure out how to get only the output colored
print("Nightly Rate-----------------------",nightly_rate)
print("Number of Nights-------------------",number_of_nights)
print("Number of Campers------------------",campers)
print()
print("Campsite--------------------------- $%4.2f"%campsite)
print("Electricity------------------------ $%4.2f"%ELECTRICITY)
print("Tax-------------------------------- $%4.2f"%tax)
print("Ranger----------------------------- $%4.2f"%ranger)
print("Total------------------------------ $%4.2f"%total)
print()
print("Cost Per Camper------------------- $%4.2f"%total_per)
The else in try statement is unnecessary. You can just put the break in the the end of the try statement. REF
In the end, in the print statements, I recommend you to use another types of formatting. You can use '...{}..'.format(..) or further pythonic is f'...{val}'. Your method is the oldest. More ref
You can remove both the outer while loops, as break is seen there at the top level, so the loops runs once only.
You can convert colors to an Enum class if desired (this is more of a stylistic choice tbh)
The line tax=(ELECTRICITY*0.07)+(campsite*0.07) can be represented as x*0.07 + y*0.07, which can be simplified to 0.07(x+y) or 0.07 * (ELECTRICITY + campsite) in this case.
Instead of manually padding the - characters in the print statements, you can use f-strings with simple formatting trick.
For example, try this out:
width = 40
fill = '-'
tax = 1.2345
print(f'{"Tax":{fill}<{width}} ${tax:4.2f}')

How to solve the error in the following program which is written Functional Programming way? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Question: Write a program that reads table with given columns from input stream. Columns are name, amount, debt. Then filter the table (condition: debt is equal to 0). After that increase debt by 42% then print results.
I am a beginner in Python and have tried multiple times but still couldn't fixed the problem. Help will be much appreciated.
Input:
10
Tatiana Santos 411889 36881
Yuvraj Holden 121877 0
Theia Nicholson 783887 591951
Raife Padilla 445511 0
Hamaad Millington 818507 276592
Maksim Whitehead 310884 0
Iosif Portillo 773233 0
Lachlan Daniels 115100 0
Evie-Grace Reese 545083 0
Ashlea Cooper 68771 0
Required Output:
Tatiana Santos 411889 52371.02
Theia Nicholson 783887 840570.42
Hamaad Millington 818507 392760.64
My Solution:
def input_data(n):
tup = []
if n>0:
tup.append(tuple(map(str,input().split(" "))))
input_data(n-1) #I know there's a problem in the recursion. I am not #doing anything with the return value. Please help
return tup
def filtertuple(* tup): # After debugged I got to know at this point only one row is passed to function
newtuple = filter(lambda i: i[2]!=0,tup)
return tuple(newtuple)
def increasedebt(newtuple):
newtuple1 = tuple(map(lambda i:(i[2])*(142/100)),newtuple)
return (newtuple1)
def output_data():
n=int(input())
return n
print(increasedebt(filtertuple(input_data(output_data()))))
Error: Traceback (most recent call last):
File "C:\Users\msi-pc\PycharmProjects\ProgramminglanguageTask3\main.py",
line 28, in <module>
print(increasedebt(filtertuple(input_data(output_data()))))
File "C:\Users\msi-pc\PycharmProjects\ProgramminglanguageTask3\main.py",
line 14, in filtertuple
return tuple(newtuple)
File "C:\Users\msi-pc\PycharmProjects\ProgramminglanguageTask3\main.py",
line 12, in <lambda>
newtuple = filter(lambda i: i[2] != 0, tup)
IndexError: list index out of range
I see two main issues with how your code passes the data from input_data to filtertuple.
The first issue is that your recursion in input_data is messed up, you never do anything with the results of the recursive calls so only the first row of input data gets included in the final return value. Recursion really isn't an ideal approach to this problem, a loop would be a lot simpler and cleaner. But you could make the recursion work, if you do something with the value returned to you, like tup.extend(intput_data(n-1)). If you stick with recursion, you'll also need to make the base case return something appropriate (or add an extra check for None), like an empty list (or tuple).
The second issue is that filtertuple is written to expect many arguments, but you're only passing it one. So tup will always be a 1-tuple containing the actual argument. If you're expecting the one argument to be a list of tuples (or tuple of tuples, I'm not sure exactly what API you're aiming for), you shouldn't use *tup in the argument list, just tup is good without the star. You could call filtertuple(*input_data(...)) which would unpack your tuple of tuples into many arguments, but that would be silly if the function is just going to pack them back up into tup again.
There may be other issues further along in the code, I was only focused on the input_data and filtertuple interactions, since that's what you were asking about.
Here's my take on solving your problem:
def gather_data(num_lines):
if num_lines == 0: # base case
return [] # returns an empty list
data = gather_data(num_lines-1) # recursive case, always gives us a list
row = tuple(map(int, input().split(" "))) # get one new row
data.append(row) # add it to the existing list
return data
def filter_zeros(data): # note, we only expect one argument (a list of tuples)
return list(filter(lambda i: i[1] != 0, data))
def adjust_debt(data): # this only returns a single column, should it return
return list(map(lambda i: (i[1]) * (142 / 100), data)) # the whole table?
# calling code:
num_lines = int(input()) # this code really didn't deserve its own function
data = gather_data(num_lines) # extra variables help debugging
filtered = filter_zeros(data) # but they could be dropped later
adjusted = adjust_debt(filtered)
print(adjusted)
I did find one extra issue, you had the parentheses wrong in the function I renamed to adjust_debt.

Python sort by objects [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
How can I sort by name and age in PYTHON?
I have the following list in .txt file:
John, 14
Mike, 18
Marco, 25
Michael, 33
I want to sort this by name and by age. I wrote this code but it doesn't work:
file = open("people.txt", "r")
data = file.readlines()
i = 0
for line in data:
name, age = line.split(',')
list = [name, age]
i += 1
print("For sorting by name press (1);")
print("For sorting by age press (2);")
z = eval(input())
if z == 1:
list.sort(key=lambda x: x.name, reverse=True)
print([item.name for item in list])
Thank you very much guys :)
Here's one approach:
with open("so.txt", "r") as f:
lines = [line.split(',') for line in f]
print("For sorting by name press (1);")
print("For sorting by age press (2);")
z = int(input())
if z == 1:
lines.sort(key=lambda x: x[0], reverse=True)
print([item[0] for item in lines])
Using:
a context manager to handle automatic file closure (this is the with)
the for line in f iterator to loop over the file's lines one at a time
a list comprehension to split the lines into lists as needed
int instead of eval
changing all line.name references to line[0] -- you could make the lines proper classes (or namedtuples if you wanted the .name access.
Though, in general, solutions for parsing csv files exist (e.g. csv -- there were a few more issues in your code than just that.

struggling with python homework [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I got a .txt file with some lines in it:
325255, Jan Jansen
334343, Erik Materus
235434, Ali Ahson
645345, Eva Versteeg
534545, Jan de Wilde
345355, Henk de Vries
Write a program that starts with opening the file kaartnummers.txt
Determine the number of lines and the largest card number in the file. Then print these data.
my code isnt finished yet but i tried atleast!:
def kaartinfo():
lst = []
infile = open('kaartnummers.txt', 'r')
content = infile.readlines()
print(len(content))
for i in content:
print(i.split())
kaartinfo()
I know that my program opens the file and counts the number of lines in it.. all after that is wrong <3
I can't figure out how to get the max number in the list.. Please if you got an answer use simple readable Python Language.
I'm not good at python, and there are probably much more elegant solutions, but this is how I would do it. Some may say this is like C++/Java in python, which many tend to avoid.
def kaartinfo():
lst = []
infile = open('kaartnummers.txt', 'r')
content = infile.readlines()
for i in content:
value = i.split(',')
value[0] = int(value[0])
lst.append(value)
return lst
Use the kaartinfo() function to retrieve a list
my_list = kaartinfo()
Assume first value is the maximum
maximumValue = my_list[0][0]
Go through every value in the list, check if they are greater than the current maximum
# if they are, set them as the new current maximum
for ele in my_list:
if ele[0] > maximumValue:
maximumValue = ele[0]
when the above loop finishes, maximum value will be the largest value in the list.
#Convert the integer back to a string, and print the result
print(str(maximumValue) + ' is the maximum value in the file!')
This should be enough to do the job:
with open('kaartnummers.txt', 'r') as f:
data = f.readlines()
print('There are %d lines in the file.' % len(data))
print('Max value is %s.' % max(line.split(',')[0] for line in data))
Given the input file you provided, the output would be:
There are 6 lines in the file.
Max value is 645345.
Of course, you can put it in a function if you like.

Python letter frequency mapping [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have a Python script that reads in a encrypted text file and decrypts it in various ways. The last 2 options I am trying to add are to map out the most frequent letters of the file and the most frequent letters in the English language.
Here are my previous functions that display frequency:
def functOne:
Crypt = input("what file would you like to select? ")
filehandle = open(Crypt, "r")
data = filehandle.read().upper()
char_counter = collections.Counter(data)
for char, count in char_counter.most_common():
if char in string.ascii_uppercase:
print(char, count)
def FunctTwo:
print "Relative letter Freq of letters in English Language A-Z; ENGLISH = (0.0749, 0.0129, 0.0354, 0.0362, 0.1400, 0.0218, 0.0174, 0.0422, 0.0665, 0.0027, 0.0047, 0.0357, 0.0339, 0.0674, 0.0737, 0.0243, 0.0026, 0.0614, 0.0695, 0.0985, 0.0300, 0.0116, 0.0169, 0.0028, 0.0164, 0.0004)"
Here's the description of what I need to do for the next two:
Function 3:
Map the most frequent letter in text to the most frequent in the English language in descending order.
[letter in cryptogram] -> [letter in english language]
Function 4:
Allow user to manually edit frequency maps
How would I go about doing this? I'm kinda lost on the mapping part, at least combing the two frequencies and allow editing.
First, you have to turn your code into actual valid Python code. For example, your functions have to be defined with a list of arguments.
Then, you have to do is return values rather than just printing them.
Also, you don't want a string representation of a tuple of frequencies, but an actual tuple of them that you can use.
And finally, you're going to have to put the two collections into some kind of format that can be compared. ENGLISH is just a sequence of 26 frequencies; the value computed by functOne is a sequence of up to 26 (letter, count) pairs in descending order of frequency. But really, we don't need the counts or the frequencies at all; we just need the letters in descending order of frequency.
In fact, if you look at it, functTwo is completely unnecessary—it's effectively computing a constant, so you might as well just do that at module level.
While we're at it, I'd reorganize functOne so it takes the input as an argument. And close the file instead of leaking it. And give the functions meaningful names.
def count_letters(data):
data = data.upper()
char_counter = collections.Counter(data)
return [char for char, count in char_counter.most_common()]
english_freqs = (0.0749, 0.0129, 0.0354, 0.0362, 0.1400, 0.0218, 0.0174,
0.0422, 0.0665, 0.0027, 0.0047, 0.0357, 0.0339, 0.0674,
0.0737, 0.0243, 0.0026, 0.0614, 0.0695, 0.0985, 0.0300,
0.0116, 0.0169, 0.0028, 0.0164, 0.0004)
pairs = zip(english_freqs, string.ascii_uppercase)
english_letters = [char for count, char in sorted(pairs, reversed=True)]
def decrypt(data):
input_letters = count_letters(data)
return {input_letter: english_letter
for input_datum, english_datum in zip(input_letters, english_letters)}
crypt = input("what file would you like to select? ")
with open(crypt, "r") as f:
data = f.read()
mapping = decrypt(data)
For the editing feature… you'll have to design what you want the interface to be, before you can implement it. But presumably you're going to edit the english_freqs object (which means you may want to use a list instead of a tuple) and rebuild english_letters from it (which means you may want that in a function after all).

Categories

Resources