mdinar
mdinar

Reputation: 33

File is created but cannot be written in Python

I am trying to write some results I get from a function for a range but I don't understand why the file is empty. The function is working fine because I can see the results in the console when I use print. First, I'm creating the file which is working because it is created; the output file name is taken from a string, and that part is working too. So the following creates the file in the given path:

report_strategy = open(output_path+strategy.partition("strategy(")[2].partition(",")[0]+".txt", "w")

it creates a text file with the name taken from a string named "strategy", for example:

strategy = "strategy(abstraction,Ent_parent)"

a file called "abstraction.txt" is created in the output path folder. So far so good. But I can't get to write anything to this file. I have a range of a few integers

maps = (175,178,185)

This is the function:

def strategy_count(map_path,map_id)

The following loop does the counting for each item in the range "maps" to return an integer:

for i in maps:
  report_strategy.write(str(i), ",", str(strategy_count(maps_path,str(i))))

and the file is closed at the end:

report_strategy.close()

Now the following:

 for i in maps:
   print str(i), "," , strategy_count(maps_path,str(i))

does give me what I want in the console:

175 , 3
178 , 0
185 , 1

What am I missing?! The function works, the file is created. I see the output in the console as I want, but I can't write the same thing in the file. And of course, I close the file.

This is a part of a program that reads text files (actually Prolog files) and runs an Answer Set Programming solver called Clingo. Then the output is read to find instances of occurring strategies (a series of actions with specific rules). The whole code:

import pmaps
import strategies
import generalization

# select the strategy to count:
strategy = strategies.abstraction_strategy

import subprocess

def strategy_count(path,name):
    p=subprocess.Popen([pmaps.clingo_path,"0",""],
                       stdout=subprocess.PIPE,stderr=subprocess.STDOUT,stdin=subprocess.PIPE)
    #
    ## write input facts and rules to clingo

    with open(path+name+".txt","r") as source:
        for line in source:
            p.stdin.write(line)

    source.close()
#    some generalization rules added
    p.stdin.write(generalization.parent_of)
    p.stdin.write(generalization.chain_parent_of)
#   add the strategy    
    p.stdin.write(strategy)

    p.stdin.write("#hide.")
    p.stdin.write("#show strategy(_,_).")
    #p.stdin.write("#show parent_of(_,_,_).")

    # close the input to clingo
    p.stdin.close()

    lines = []
    for line in p.stdout.readlines():
        lines.append(line)

    counter=0    
    for line in lines:
        if line.startswith('Answer'):
            answer = lines[counter+1]
            break
        if line.startswith('UNSATISFIABLE'):
            answer = ''
            break
        counter+=1
    strategies = answer.count('strategy')
    return strategies

# select which data set (from the "pmaps" file) to count strategies for:
report_strategy = open(pmaps.hw3_output_path+strategy.partition("strategy(")[2].partition(",")[0]+".txt", "w")
for i in pmaps.pmaps_hw3_fall14:
    report_strategy.write(str(i), ",", str(strategy_count(pmaps.path_hw3_fall14,str(i))))
report_strategy.close()

# the following is for testing the code. It is working and there is the right output in the console
#for i in pmaps.pmaps_hw3_fall14:
#   print str(i), "," , strategy_count(pmaps.path_hw3_fall14,str(i))

Upvotes: 0

Views: 120

Answers (2)

mdinar
mdinar

Reputation: 33

The problem was with the write which as @user2357112 mentioned takes only one argument. The solution could also be joining the strings with + or join():

for i in maps:
 report.write(str(i)+ ","+str(strategy_count(pmaps.path_hw3_fall14,str(i)))+"\n")

@user2357112 your answer might have the advantage of knowing if your test debug in the console produces the write answer, you just need to write that. Thanks.

Upvotes: 0

user2357112
user2357112

Reputation: 280181

write takes one argument, which must be a string. It doesn't take multiple arguments like print, and it doesn't add a line terminator.

If you want the behavior of print, there's a "print to file" option:

print >>whateverfile, stuff, to, print

Looks weird, doesn't it? The function version of print, active by default in Python 3 and enabled with from __future__ import print_function in Python 2, has nicer syntax for it:

print(stuff, to, print, out=whateverfile)

Upvotes: 1

Related Questions