I have less than a year of programming experience. While learning about reading and writing files I came across this tutorial: http://www.penzilla.net/tutorials/python/fileio/
The tutorial offers the following example as a simple script to create and write to a file:
# Let's create a file and write it to disk.
filename = "test.dat"
# Let's create some data:
done = 0
namelist = []
while not done:
name = raw_input("Enter a name:")
if type(name) == type(""):
namelist.append(name)
else:
break
# Create a file object:
# in "write" mode
FILE = open(filename,"w")
# Write all the lines at once:
FILE.writelines(namelist)
# Alternatively write them one by one:
for name in namelist:
FILE.write(name)
FILE.close()
I copied this code and ran it through a Python 2.7.3 Shell. I am prompted repeatedly to enter strings which are appended to a list that will be written to a file (this makes sense to me). What I don't understand is the condition for exiting the While loop ("While not done:"). I thought this meant that I type done at the prompt to exit the loop and subsequently write the file, but done has no effect. Then I thought that any non-string entered at the prompt should break the loop and write the file. I couldn't get the loop to break at all; for anything I entered at the prompt, I was just prompted again with "Enter a name:".
By removing the While loop and retaining the if/else statement, I got the code to work for a single prompt. Can someone tell me what I am not understanding here? I am guessing it is a fairly simple concept that wasn't explained in the tutorial because it was assumed to be obvious. Since "done" is such a common word, I wasn't able to find any Python specific meanings for it.
I would stop following that tutorial right now. The code isn't Pythonic, it's way too complicated, and it seems to be pretty outdated.
That being said, here's how I'd write that tutorial's code (yes, it does the same thing, but only the right way):
with open('test.dat', 'w') as handle:
while True:
name = raw_input('Enter a name: ')
if not name:
break
handle.write(name + '\n')
done is assigned once on line 3:
done = 0
Therefore, this the while loop will continue to loop as long as done is still "not 0":
while not done:
I.e. it will continue to loop forever, unless it hits a break statement (line 11). Unfortunately, the code is flawed and that will never happen.
If you want to stop when you type 'done', then change the if statement to:
if name == "done":
But, be aware that the literal string done above has nothing to do with the variable done assigned earlier.
It's not your fault. That code provides no way to break out of the loop.
if name == 'end':
break
The code is bad, firstly.
In this case, done is the name of a variable. As written, it will loop forever since there's no way to exit.
You should stop following that tutorial and pick a better one: http://wiki.python.org/moin/BeginnersGuide/NonProgrammers
Related
I'm trying to learn python and I'm currently stuck - I'm trying to look for more than one thing in a text document. It'll present back to me the first thing that I'm looking for ('#outlook.com' lines) however, it seemingly doesn't bother to show the second thing I'm looking for (date of birth (DOB)).
I'm not sure if I'm missing some sort of code to enable it to look for something again? I've tried writing it multiple ways but, I've run out of ideas.
I'm not sure if I need to write multiple loops for each time I want to find something?
Any help is much appreciated! Thanks
lcount = 0
for line in fhand:
lcount = lcount + 1
line = line.strip()
if not "#outlook.com" in line:
continue
print(line)
## This second set of code doesn't want to run, I know it's looking for the right thing but, it's seemingly not working
if line.startswith("DOB: "):
print(line)
##
print("There is", lcount, "lines")
I currently have the below syntax -
BEGIN PROGRAM.
import spss,spssdata
varlist = [element[0] for element in spssdata.spssdata('CARD_2_Q2_1_a').fetchall()]
varstring = " ".join(str(int(i)) for i in varlist)
spss.submit("if (Q4_2 = 2 AND CARD_2_Q2_1_a = %(varstring)s) Q4_2_FULL = %(varstring)s." %locals())
END PROGRAM.
I thought this would just loop through the values in my variable CARD_2_Q2_1_a and populate Q4_2_FULL where appropriate. It worked in long hand without Python use, but the code above doesn't change the input file at all. Any reason why this might not be working or an alternative way of doing this?
varstring will be a string of integers joined by blanks. Therefore, your test condition in the IF will never be satisfied. Hence Q4_2_FULL will never be populated. You can print out the command you are submitting to see this.
I'm not sure exactly what your desired result is, but remember that the IF command you are submitting will execute over the entire dataset.
First of all i would like to apologize since i am a beginner to Python. Anyway I have a Python Program where I can create text files with the general form:
Recipe Name:
Item
Weight
Number of people recipe serves
And what I'm trying to do is to allow the program to be able to retrieve the recipe and have the ingredients recalculated for a different number of people. The program should output the the recipe name, the new number of people and the revised quantities for the new number of people. I am able to retrieve the recipe and output the recipe however i am not sure how to have the ingredients recaculated for a different number of people. This is part of my code:
def modify_recipe():
Choice_Exist = input("\nOkaym it looks like you want to modify a recipe. Please enter the name of this recipe ")
Exist_Recipe = open(Choice_Exist, "r+")
time.sleep(2)
ServRequire = int(input("Please enter how many servings you would like "))
I would recommend splitting your effort into multiple steps, and working on each step (doing research, trying to write the code, asking specific questions) in succession.
1) Look up python's file I/O. 1.a) Try to recreate the examples you find to make sure you understand what each piece of the code does. 1.b) Write your own script that accomplishes just this piece of your desired program, i.e. opens an exist recipe text file or creates a new one.
2) Really use you're own functions in Python particularly with passing your own arguments. What you're trying to make is a perfect example of good "modular programming", were you would right a function that reads an input file, another that writes an output file, another that prompts users for they number they'd like to multiple, and so on.
3) Add a try/except block for user input. If a user enters a non-numeric value, this will allow you to catch that and prompt the user again for a corrected value. Something like:
while True:
servings = raw_input('Please enter the number of servings desired: ')
try:
svgs = int(servings)
break
except ValueError:
print('Please check to make sure you entered a numeric value, with no'
+' letters or words, and a whole integer (no decimals or fractions).')
Or if you want to allow decimals, you could use float() instead of int().
4) [Semi-Advanced] Basic regular expressions (aka "regex") will be very helpful in building out what you're making. It sounds like your input files will have a strict, predictable format, so regex probably isn't necessary. But if you're looking to accept non-standard recipe input files, regex would be a great tool. While it can be a bit hard or confusing skill to learn, but there are a lot of good tutorials and guides. A few I bookmarked in the past are Python Course, Google Developers, and Dive Into Python. And a fantastic tool I strongly recommend while learning to build your own regular expression patterns is RegExr (or one of many similar, like PythonRegex), which show you what parts of your pattern are working or not working and why.
Here's an outline to help get you started:
def read_recipe_default(filename):
# open the file that contains the default ingredients
def parse_recipe(recipe):
# Use your regex to search for amounts here. Some useful basics include
# '\d' for numbers, and looking for keywords like 'cups', 'tbsp', etc.
def get_multiplier():
# prompt user for their multiplier here
def main():
# Call these methods as needed here. This will be the first part
# of your program that runs.
filename = ...
file_contents = read_recipe_file(filename)
# ...
# This last piece is what tells Python to start with the main() function above.
if __name__ == '__main__':
main()
Starting out can be tough, but it's very worth it in the end! Good luck!
I had to edit it a couple times because I use Python 2.7.5, but this should work:
import time
def modify_recipe():
Choice_Exist = input("\nOkay it looks like you want to modify a recipe. Please enter the name of this recipe: ")
with open(Choice_Exist + ".txt", "r+") as f:
content = f.readlines()
data_list = [word.replace("\n","") for word in content]
time.sleep(2)
ServRequire = int(input("Please enter how many servings you would like: "))
print data_list[0]
print data_list[1]
print int(data_list[2])*ServRequire #provided the Weight is in line 3 of txt file
print ServRequire
modify_recipe()
I'm fairly new to python, but I'm making a script and I want one of the functions to update a variable from another file. It works, but when I exit the script and reload it, the changes aren't there anymore. For example (this isn't my script):
#File: changeFile.txt
number = 0
#File: changerFile.py
def changeNumber():
number += 1
If I retrieve number during that session, it will return 1, but if I exit out and go back in again and retrieve number without calling changeNumber, it returns 0.
How can I get the script to actually save the number edited in changeNumber to changeFile.txt? As I said, I'm fairly new to python, but I've looked just about everywhere on the Internet and couldn't really find an answer that worked.
EDIT: Sorry, I forgot to include that in the actual script, there are other values.
So I want to change number and have it save without deleting the other 10 values stored in that file.
Assuming, as you show, that changeFile.txt has no other content whatever, then just change the function to:
def changeNumber():
global number # will not possibly work w/o this, the way you posted!
number += 1
with open('changeFile.txt', 'w') as f:
f.write('number = {}\n'.format(number))
ADDED: the OP edited the Q to mention (originally omitted!-) the crucial fact that changefile.txt has other lines that need to be preserved as well as the one that needs to be changed.
That, of course, changes everything -- but, Python can cope!-)
Just add import fileinput at the start of this module, and change the last two lines of the above snippet (starting with with) to:
for line in fileinput.input(['changefile.txt'], inplace=True):
if line.startswith('number ');
line = 'number = {}\n'.format(number)'
print line,
This is the Python 2 solution (the OP didn't bother to tell us if using Py2 or Py3, a crucial bit of info -- hey, who cares about making it easy rather than very hard for willing volunteers to help you, right?!-). If Python 3, change the last statement from print line, to
print(line, end='')
to get exactly the same desired effect.
OK, so what my program is all about is that the user has to solve a coded puzzle which gets read in from an external file. The user then guesses what letter matches up with the symbol in the coded puzzle and they can then add this to a list of clues.
One of the options in my program allows the user to check whether the clues they have entered are correct with the solved version. The solved version is read in from an external file and this is what needs to get checked with the list of clues.
So far I have a basic piece of code but what keeps on happening is that the output I get is that " You scored 0 out of 10" even though some of the pairings I have entered are correct.
My code so far for this section of code is this...
def check_clues():
count = 0
# TRIES TO OPEN FILE SOLVED.TXT
try:
with open('solved.txt') as r:
# READS THROUGH ALL THE LINES IN SOLVED.TXT
solved = r.readlines()
# WILL DISPLAY AN ERROR MESSAGE IF SOLVED.TXT IS NOT FOUND
except:
print("Error finding file")
# WILL TRY AND OPEN THE FILE 'clues.txt'
try:
with open('clues.txt') as r:
clues = r.readlines()
except:
print("Error finding ")
# GOES THROUGH BOTH THE USERS CLUES AND SOLVED.TXT TO SEE HOW MANY CLUES ARE THE SAME
for clue in clues:
if clue in solved:
count += 1
# Prints the amount of clues the user got right out of 10
print('You got:', count, 'correct!')
Below is what is in the solved.txt file:
ACQUIRED
ALMANAC
INSULT
JOKE
HYMN
GAZELLE
AMAZON
EYEBROWS
AFFIX
VELLUM
Below is what is in clues.txt
A#
M*
N%
However please note clues.txt is the list which the user can add to. So if the user decides to enter S and &, this will add to the clues.txt as S&
Below is the file words.txt which contains the list of coded words the user has to solve...
#+/084&"
#3*#%#+
8%203:
,1$&
!-*%
.#7&33&
#*#71%
&-&641'2
#))85
9&330*
I had a hand at this, using what you're provided. I believe this is what you're looking for provided you have all the files you listed. Basically I used the words.txt and solved.txt files and created a dictionary mapping all the symbols to their correct letters. Then I used that dictionary to compare each clue to see if they match. This would increment the count and you would get your correct output.
The problem with your original code is that you're simply searching if the clue is inside of the solved text file. For example, you search if your first clue A* is inside of the words text file. Obviously it isn't because there isn't a * in that file. So you need something to baseline/compare it to. Which is why in this case I created a dictionary. I also removed your try/except loops since your program should technically never run if a file is missing. In which case your exceptions will allow the program to keep running even if a file is missing producing multiple error outputs. It should stop if no files are found or be handled specifically, not allow it to keep running as it normally would. If you go that route, I'd also advise only using except WindowsError to avoid catching any other potential exceptions.
def check_clues():
# Dictionary to hold all of the symbol/letter combos
coded_dict = {}
# Go through each symbol/letter combination together
with open("words.txt") as fw, open("solved.txt") as fs:
for fw_line, fs_line in zip(fw, fs):
for fw_symbol, fs_letter in zip(fw_line.strip(), fs_line.strip()):
# Add the symbol/letter combination to the dictionary
coded_dict[fw_symbol] = fs_letter
correct_clues = []
with open("clues.txt") as fc:
for fc_line in fc:
# If the symbol is in the dictionary and the letter matches the symbol
if fc_line[1] in coded_dict and coded_dict[fc_line[1]] == fc_line[0]:
# Add a correct clue to your list
correct_clues.append(fc_line.strip())
print("You got a total of {0} correct: {1}".format(len(correct_clues), ", ".join(correct_clues)))
if __name__ == "__main__":
check_clues()
If you need me to elaborate on anything let me know.