I am building a save system for a game im making, im trying to save all of the resources you get in the game so you can load into it the next time you play. I was going to use file.write as I saw it being used in other types of games, but it cant save the variables as ints. Is there any sort of workaround or just a different sort of saving that I could use to be able to do this?
from Resources import *
def start_new():
Q = int(input('which save file do you want to save to? 1, 2, or 3.'))
if Q == 1:
file = open("save1.txt", "w")
file.write(Manpower)
file.write(Food)
file.write(Food_Use)
file.write(Wood)
file.write(Farmers)
file.write(Food_Income)
file.write(FarmNum)
file.write(MaxFarmer)
file.write(Deforestation)
file.write(Trees)
file.write(Tree_Spread)
file = open("save1.txt", "r")
Convert integer values to string. You can do this using several method. Lets write Manpower(Assuming type of this variable is int) to file to be an example:
A small advice, there is no need to call file.close() when using with statement. The with statement itself ensures proper acquisition and release of resources.
with open("save1.txt", 'w') as f:
f.write(str(Manpower))
or even better:
with open("save1.txt", 'w') as f:
f.write(f"{Manpower}\n")
\n is EOL(End Of Line) character. After EOL character, new writes will be in next line. You can use it to separate and identify values while reading them again.
On you code you need to close the file after make changes...
file.close()
Your code:
from Resources import *
def start_new():
Q = int(input('which save file do you want to save to? 1, 2, or 3.'))
if Q == 1:
file = open("save1.txt", "w")
file.write(Manpower)
file.write(Food)
file.write(Food_Use)
file.write(Wood)
file.write(Farmers)
file.write(Food_Income)
file.write(FarmNum)
file.write(MaxFarmer)
file.write(Deforestation)
file.write(Trees)
file.write(Tree_Spread)
file.close()
file = open("save1.txt", "r")
# stuff
file.close()
Related
Okay, So I´m doing a program that simulates dice rolls and then saves them to a file.
I thought that the easiest option, in my opinion, would be to just save every single iteration of the loop and save the print to the file line by line. But unfortunately, I cannot figure it out.
import random
output=[]
order=0
inpu_t=int(input("Enter the number of simulated throws: "))
f = open('file.txt','w')
figures = (0,)*6
for i in range(inpu_t):
order = order+1
throw = random.randint(1, 6)
figure = figures[throw -1]+1
print(order,'.throw and {}-times fell the number {}.'.format(figure, throw ))
output.append(order)
output.append(figure)
output.append(throw )
figures = figures[:throw -1]+(figure,)+figures[throw :]
print("\n")
with open('file.txt', 'w') as f:
for item in output:
f.write("%s" % item)
for i in range(6):
print('The number {} fell {}-times.'.format(i+1, figures[i]))
Secondly, I thought I could save all the variables to the list and then somehow through some function save it to a file.
output.append(order)
output.append(figure)
output.append(throw )
There I added all the data to the list.
with open('file.txt', 'w') as f:
for item in output:
f.write("%s" % item)
I added it to the file here.
My output in the file is this: "115216314412511"
I don't know how I should do it so that all 3 numbers are would be together in one line like in the code.
print(order,'.throw and {}-times fell the number {}.'.format(figure, throw ))
Append a Carriage Return "/r" with in the for loop after the append throw
hi the better way is to use logging instead to open each time file
read here : How to write to a file, using the logging Python module?
I have a large text file in python. I want to split it into 2, using a keyword. The file above the keyword must be copied to one file and the rest of the file into other. I want to save these files with different extensions in the same directory. Please help me with this.
Also, how to convert a file from one format to another format?
For example, .txt to .xml or .cite to .xml ?
To answer the first part of your question, you can simply use the split function after reading the text and write them to your new files:
with open('oldfile.txt', 'r') as fh:
text_split = fh.read().split(keyword)
with open('newfile' + extension1, 'w') as fh:
fh.write(text_split[0])
with open('newfile' + extension2, 'w') as fh:
# If you know that the keyword only appears once
# you can changes this to fh.write(text_split[1])
fh.write(keyword.join(text_split[1:]))
The second part of your question is much more difficult. I don't know what kind of file format that you are working with, but txt files are just plain text with no specific structure. XML files cannot be converted from any arbitrary format. If you are working with XML files with a .txt format, you can simply change the format to XML, but if you are looking to convert a format like CSV, I suggest you use a library such as lxml.
Edit: If the file does not fit into memory, then you can iterate through the lines instead:
with open('oldfile.txt', 'r') as fh:
fh_new = open('newfile' + extension1, 'w')
keyword_found = False
line = fh.readline()
while line:
if not keyword_found:
text_split = line.split(keyword)
fh_new.write(text_split[0])
if len(text_split) > 1:
fh_new.close()
keyword_found = True
fh_new = open('newfile' + extension2, 'w')
fh_new.write(text_split[1:])
else:
fh_new.write(line)
line = fh.readline()
fh_new.close()
about splitting your file this should do it( considering the largeness of the file):
import mmap
regex=b'your keyword'
f=open('your_path_to_the_main_file','rb')
s = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
first_occurance_position=s.find(regex)
if(first_occurance_position==0)
print('this is a mistake')
f.close()
quit()
buf_size=0xfff
first_part_file=open('your_path_to_the_first_part'+'.its_extension','wb')
second_part_file=open('your_path_to_the_second_part'+'.its_extension','wb')
i=0;
if(buf_size>len(regex)):
buf_size=len(regex)
b=f.read(buf_size)
while(b):
i=i+buf_size
first_part_file.write(b)
if(i==first_occurance_position):
break
if(first_occurance_position-i<buf_size):
buf_size=first_occurance_position-i
b=f.read(buf_size)
b=f.read(0xffff)
while(b):
second_part_file.write(b)
b=f.read(0xffff)
first_part_file.close()
second_part_file.close()
f.close()
I have a txt file with strings assigned to each other like "sun - moon" and I want to get the assigned value (no matter which one) of a particular string if it would come from user input, and if not then create a new pair for file and write it to it:
user_input = input()
if user_input in open('base.txt').read():
print(True) # it's just to be sure that everything really works
else:
base_file = open('base.txt', 'a+')
base_file.write(user_input)
base_file.write('\n')
base_file.close()
import pickle
myDictA = {'sun': 'moon'}
with open('myFile.pkl', 'w') as file:
pickle.dump(myDict, file)
with open('myFile.pkl', 'r') as file:
myDictB = pickle.load(file)
print("myDictA:", myDictA)
print("myDictB:", myDictB)
you can also integrate gzip in the file save load process to save disk space if you want. Another option is to use cPickle which should be written the same way and is said to be up to 1000x faster.
A little addition to the current code.
user_input = input()
flag=1
with open('base.txt') as f:
data=f.read()
if user_input in data:
print(data)
flag=0
if flag:
base_file = open('base.txt', 'a+')
base_file.write(user_input)
base_file.write('\n')
base_file.close()
The files I have seem to be in a "dict" format...
file header is as follows: time,open,high,low,close,volume
next line is as follows:
{"t":[1494257340],"o":[206.7],"h":[209.3],"l":[204.50002],"c":[204.90001],"v":[49700650]}`
import csv
with open ('test_data.txt', 'rb') as f:
for line in f:
dict_file = eval(f.read())
time = (dict_file['t']) # print (time) result [1494257340]
open_price = (dict_file['o']) # print (open_price) result [206.7]
high = (dict_file['h']) # print (high) result [209.3]
low = (dict_file['l']) # print (low) result [204.50002]
close = (dict_file['c']) # print (close) result [204.90001]
volume = (dict_file['v']) # print (volume) result [49700650]
print (time, open_price, high, low, close, value)
# print result [1494257340] [206.7] [209.3] [204.50002] [204.90001] [49700650]
# I need to remove the [] from the output.
# expected result
# 1494257340, 206.7, 209.3, 204.50002, 204.90001, 49700650
the result I need is (change time ("epoch date format") to dd,mm,yy
5/8/17, 206.7, 209.3, 204.50002, 204.90001, 49700650
so I know I need the csv.writer function
I see a number of problems in the code you submitted. I recommend you to break your task into small pieces and see if you can make them work individually. So what are you trying to do is:
open a file
read the file line by line
eval each line to get a dict object
get values from that object
write those values in a (separate?) csv file
Right?
Now do each one, one small step at the time
opening a file.
You're pretty much on point there:
with open('test_data.txt', 'rb') as f:
print(f.read())
# b'{"t":[1494257340],"o":[207.75],"h":[209.8],"l":[205.75],"c":[206.35],"v":[61035956]}\n'
You can open the file in r mode instead, it will give you strings instead of byte type objects
with open('test_data.txt', 'r') as f:
print(f.read())
# {"t":[1494257340],"o":[207.75],"h":[209.8],"l":[205.75],"c":[206.35],"v":[61035956]}
It might cause some problems but should work since eval can handle it just fine (at least in python 3)
read the file line by line
with open('test_data.txt', 'rb') as f:
for line in f:
print(line)
# b'{"t":[1494257340],"o":[207.75],"h":[209.8],"l":[205.75],"c":[206.35],"v":[61035956]}\n'
Here is another problem in your code, you're not using line variable and trying to f.read() instead. This will just read entire file (starting from the second line, since the first one is been read already). Try to swap one for another and see what happens
eval each line to get a dict object
Again. This works fine. but I would add some protection here. What if you get an empty line in the file or a misformatted one. Also if this file comes from an untrusted source you may become a victim of a code injection here, like if a line in your file changed to:
print("You've been hacked") or {"t":[1494257340],"o":[207.75],"h":[209.8],"l":[205.75],"c":[206.35],"v":[61035956]}
with open('test_data.txt', 'rb') as f:
for line in f:
dict_file = eval(line)
print(dict_file)
# You've been hacked
# {'t': [1494257340], 'o': [207.75], 'h': [209.8], 'l': [205.75], 'c': [206.35], 'v': [61035956]}
I don't know your exact specifications, but you should be safer with json.loads instead.
...
Can you continue on your own from there?
get values from the object
I think dict_file['t'] doesn't give you the value you expect.
What does it give you?
Why?
How to fix it?
write those values in a csv file
Can you write some random string to a file?
What scv format looks like? Can you format your values to match it
Check the docs for csv module, can it be of help to you?
And so on and so forth...
EDIT: Solution
# you can save the print output in a file by running:
# $ python convert_to_csv.py > output.cvs
import datetime, decimal, json, os
CSV_HEADER = 'time,open,high,low,close,volume'
with open('test_data.txt', 'rb') as f:
print(CSV_HEADER)
for line in f:
data = json.loads(line, parse_float=decimal.Decimal)
data['t'][0] = datetime.datetime.fromtimestamp(data['t'][0]) \
.strftime('%#d/%#m/%y' if os.name == 'nt' else '%-d/%-m/%y')
print(','.join(str(data[k][0]) for k in 'tohlcv'))
Running:
$ cat test_data.txt
{"t":[1494257340],"o":[207.75],"h":[209.8],"l":[205.75],"c":[206.35],"v":[61035956]}
{"t":[1490123123],"o":[107.75],"h":[109.8],"l":[105.75],"c":[106.35],"v":[11035956]}
{"t":[1491234234],"o":[307.75],"h":[309.8],"l":[305.75],"c":[306.35],"v":[31035956]}
$ python convert_to_csv.py
time,open,high,low,close,volume
8/5/17,207.75,209.8,205.75,206.35,61035956
21/3/17,107.75,109.8,105.75,106.35,11035956
3/4/17,307.75,309.8,305.75,306.35,31035956
I am currently keeping high scores into a text file called "score.txt". The prgoram works fine, updating the file with the new high scores as normal. Except that every time the program updates the file, there is always one blank line before the first high score, creating an error when I try to save the scores the next time. The code:
scores_list = []
score = 10
def take_score():
# Save old scores into list
f = open("score.txt", "r")
lines = f.readlines()
for line in lines:
scores_list.append(line)
print scores_list
f.close()
take_score()
def save_score():
# Clear file
f = open("score.txt", "w")
print >> f, ""
f.close()
# Rewrite scores into text files
w = open("score.txt", "a")
for i in range(0, len(scores_list)):
new_string = scores_list[i].replace("\n", "")
scores_list[i] = int(new_string)
if score > scores_list[i]:
scores_list[i] = score
for p in range(0, len(scores_list)):
print >> w, str(scores_list[p])
print repr(str(scores_list[p]))
save_score()
The problem mentioned happens in the save_score() function. I have tried this related question: Removing spaces and empty lines from a file Using Python, but it requires I open the file in "r" mode. Is there a way to accomplish the same thing except when the file is opened in "a" mode (append)?
You are specifically printing an empty line as soon as you create the file.
print >> f, ""
You then append to it, keeping the empty line.
If you just want to clear the contents every time you run this, get rid of this:
# Clear file
f = open("score.txt", "w")
print >> f, ""
f.close()
And modify the opening to this:
w = open("score.txt", "w")
The 'w' mode truncates already, as you were already using. There's no need to truncate, write an empty line, close, then append lines. Just truncate and write what you want to write.
That said, you should use the with construct and file methods for working with files:
with open("score.txt", "w") as output: # here's the with construct
for i in xrange(len(scores_list)):
# int() can handle leading/trailing whitespace
scores_list[i] = int(scores_list[i])
if score > scores_list[i]:
scores_list[i] = score
for p in xrange(len(scores_list)):
output.write(str(scores_list[p]) + '\n') # writing to the file
print repr(str(scores_list[p]))
You will then not need to explicitly close() the file handle, as with takes care of that automatically and more reliably. Also note that you can simply send a single argument to range and it will iterate from 0, inclusive, until that argument, exclusive, so I've removed the redundant starting argument, 0. I've also changed range to the more efficient xrange, as range would only be reasonably useful here if you wanted compatibility with Python 3, and you're using Python 2-style print statements anyway, so there isn't much point.
print appends a newline to what you print. In the line
print >> f, ""
You're writing a newline to the file. This newline still exists when you reopen in append mode.
As #Zizouz212 mentions, you don't need to do all this. Just open in write mode, which'll truncate the file, then write what you need.
Your opening a file, clearing it, but then you open the same file again unnecessarily. When you open the file, you print a newline, even if you don't think so. Here is the offending line:
print >> f, ""
In Python 2, it really does this.
print "" + "\n"
This is because Python adds a newline at the end of the string to each print statement. To stop this, you could add a comma to the end of the statement:
print "",
Or just write directly:
f.write("my data")
However, if you're trying to save a Python data type, and it does not have to be human-readable, you may have luck using pickle. It's really simple to use:
def save_score():
with open('scores.txt', 'w') as f:
pickle.dump(score_data, f):
It is not really answer for question.
It is my version of your code (not tested). And don't avoid rewriting everything ;)
# --- functions ---
def take_score():
'''read values and convert to int'''
scores = []
with open("score.txt", "r") as f
for line in f:
value = int(line.strip())
scores.append(value)
return scores
def save_score(scores):
'''save values'''
with open("score.txt", "w") as f
for value in scores:
write(value)
write("\n")
def check_scores(scores, min_value):
results = []
for value in scores:
if value < min_value:
value = min_value
results.append(value)
return resulst
# --- main ---
score = 10
scores_list = take_score()
scores_list = check_scores(scores_list, score)
save_score(scores_list)