Python - Dictionary - If loop variable not changing - python

Project is about to convert short forms into long description and read from csv file
Example: user enters LOL and then it should response 'Laugh of Laughter'
Expectation: Till the time time user enter wrong keyword computer keep on asking to enter short form and system answers it's long description from CSV file
I considered each row of CSV file as dictionary and broke down into keys and values
logic used: - Used while so, that it keeps on asking until short column didn't finds space, empty cell. But issue is after showing successful first attempt comparison in IF loop is not happening because readitems['short' ] is not getting updated on each cycle
AlisonList.csv Values are:
short,long
lol,laugh of laughter
u, you
wid, with
import csv
from lib2to3.fixer_util import Newline
from pip._vendor.distlib.util import CSVReader
from _overlapped import NULL
READ = "r"
WRITE = 'w'
APPEND = 'a'
# Reading the CSV file and converted into Dictionary
with open ("AlisonList.csv", READ) as csv_file:
readlist = csv.DictReader(csv_file)
# Reading the short description and showing results
for readitems in readlist:
readitems ['short'] == ' '
while readitems['short'] !='' :
# Taking input of short description
smsLang = str(input("Enter SMS Language : "))
if smsLang == readitems['short']:
print(readitems['short'], ("---Means---"), readitems['long'])
else:
break

Try this:
import csv
READ = "r"
WRITE = 'w'
APPEND = 'a'
# Reading the CSV file and converted into Dictionary
with open ("AlisonList.csv", READ) as csv_file:
readlist = csv.DictReader(csv_file)
word_lookup = { x['short'].strip() : x['long'].strip() for x in readlist }
while True:
# Taking input of short description
smsLang = str(input("Enter SMS Language : ")).lower()
normalWord = word_lookup.get(smsLang.lower())
if normalWord is not None:
print(f"{smsLang} ---Means--- {normalWord}")
else:
print(f"Sorry, '{smsLang}' is not in my dictionary.")
Sample output:
Enter SMS Language : lol
lol ---Means--- laugh of laughter
Enter SMS Language : u
u ---Means--- you
Enter SMS Language : wid
wid ---Means--- with
Enter SMS Language : something that won't be in the dictionary
Sorry, 'something that won't be in the dictionary' is not in my dictionary.
Basically, we compile a dictionary from the csv file, using the short words as the keys, and the long words as the items. This allows us in the loop to then just call word_lookup.get(smsLang) to find the longer version. If such a key does not exist, we get a result of None, so a simple if statement can handle the case where there is no longer version.
Hope this helps.

Related

How can I remove double quotations surrounding a list imported from a file in Python?

I'm trying to create a food storage application that tracks the items put in a food storage facility and recalls them for the user. This is a very early prototype of the program, only capable of tracking the information locally, but I ran into some problems with it. So my apologies if this code is unreadable, I just can't find a solution to my problem explained below.
print("Food Storage Application V1.0 - LOCAL ONLY")
UPC_List = []
with open('UPCList.txt', 'r') as file:
for UPCentry in file:
location = UPCentry[:-1]
UPC_List.append(location)
print(UPC_List)
global i
i = 0
UPC_Input = ''
UPC_Count = 0
while True:
UPC_Found = False
UPC_Input = input("Enter UPC or enter 'end' to quit: ")
if UPC_Input == "end":
with open("UPCList.txt", "w") as file:
for UPCsave in UPC_List:
file.write('%s\n' % UPCsave)
break
try:
UPC_Input = int(UPC_Input)
except ValueError as v:
print(f"Input '{UPC_Input}' is not an acceptable UPC")
continue
# print(UPC_List) # for debugging
def newProduct(UPC):
global UPC_Count
product_name = input(f"Enter name of item {UPC}: ")
product_quantity = input(f"Enter quantity of item {UPC}: ")
try:
product_quantity = int(product_quantity)
except ValueError as v:
print("Invalid quantity. Please enter a number.")
newProduct(UPC_Input)
product_unit = input(f"Enter unit type (box, bunch, can, etc...) of item {UPC}: ")
print(f"You have added: \n {product_name} \n {UPC} \n Quantity: {product_quantity} \n Unit: {product_unit}")
UPC_List.insert(UPC_Count, [UPC, product_name, product_quantity, product_unit])
UPC_Count += 1
def existingProduct(UPC):
for sublist in UPC_List:
if str(UPC) in str(sublist):
UPC = int(UPC)
print(f"Position: {UPC_List.index(sublist)} {sublist.index(UPC)}")
position = UPC_List.index(sublist)
addition = input(f"Enter the number of items to add to '{UPC_List[position][1]}' (Default entry: +1): ")
try:
addition = int(addition)
except ValueError as v:
addition = 0
if addition == 0:
UPC_List[position][2] += 1
else:
UPC_List[position][2] += addition
print(f"New Quantity for item '{UPC_List[position][1]}': {UPC_List[position][2]}")
#Find if UPC Exists
for UPC in UPC_List:
if UPC[0] == UPC_Input:
print("UPC Found")
existingProduct(UPC_Input)
UPC_Found = True
if UPC_Found == False:
newProduct(UPC_Input)
This is my code so far. I made a version of it without the read and writing to file lines and it worked great, but I'm stumped on getting the code to read a list from a file and use it in the code. It saves the list, but it won't retrieve it correctly. I found what I think is the problem by using that print(UPC_List) line, which prints ["[2, 'banana', 2, 'bunch']"] (that was a test entry I loaded into the file using the program). I think the problem lies in the double quotes on the outside of the list. This is a nested list, so those quotation marks lead to an index error when I try to access the list.
If this isn't enough info, I can try to provide more. I'm very new to python and coding in general so this was my best attempt at the script.
You are reading each list in as a string.
You can use the python eval function to convert a string into its evaluated form:
my_list_string = "['item1', 'item2']"
my_list = eval(my_list_string)
To reproduce and solve, we need a minimal reproducible example including
the input (file contents posted as plain-text in code-block formatting)
the minimal code to reproduce
Input file
Contents of UPCList.txt:
[2, 'banana', 2, 'bunch']
This is the string-representation of a list in Python (like str(list)). Probably it was written by your program.
Code
a minimal reproducible example (only first few lines to print the read list):
upc_locations = []
with open('UPCList.txt', 'r') as file:
for upc in file:
location = upc[:-1]
upc_locations.append(location)
print(upc_locations)
Prints:
["[2, 'banana', 2, 'bunch']"]
Debug
add some debug print for each line read
upc_locations = []
with open('UPCList.txt', 'r') as file:
for line in file:
print(line)
location = line[:-1] # read all chars from line until last (excluding)
print(location)
upc_locations.append(location)
print(upc_locations)
Prints:
[2, 'banana', 2, 'bunch']
[2, 'banana', 2, 'bunch']
["[2, 'banana', 2, 'bunch']"]
Note:
the second empty-line is the line-break \n at the end of the file's line.
the first line contains something like a Python list with strings and numbers
the third line has removed the line-break.
Fix
The line can be parsed as JSON array. Therefore we need to replace the single-quotes by double-quotes first.
import json
upc_locations = []
with open('UPCList.txt', 'r') as file:
for line in file:
cleaned = line.strip() # remove the line-break and any surrounding whitespace
print(cleaned)
valid_json = cleaned.replace("'", '"') # replace single quotes by double quotes to have valid JSON strings
array = json.loads(valid_json)
print(array)
for element in array:
upc_locations.append(element)
print(upc_locations)
Prints:
[2, 'banana', 2, 'bunch']
[2, u'banana', 2, u'bunch']
[2, u'banana', 2, u'bunch']
Tip: save your objects as JSON to a file
When saving objects from your programs to a plain text-file it is recommended to use a standard format like CSV, XML or JSON.
So you can use standard-parsers to read it (back).
For example:
import json
def save(list):
with open("UPCList.txt", "w") as file:
json.dump(list, file)
# file.write('%s\n' % UPCsave)
def load():
with open("UPCList.txt", "r") as file:
return json.load(file)
Note:
The out-commented line wrote the list in Python's string-representation (see precent-formatting %s). Thus we had to replace the double-quotes when reading.
The json-dump writes a list as JSON-array. This format is readable by many programs and tools and the defacto web-standard.
See also:
Write JSON objects to file using python
Reading JSON from a file?

Python- how to write to text file without deleting contents

I am new to programming and was wondering if anyone can help me. I have created a program below that enables me to write to the text file. I have a third Column called flower_quantity. I was wondering how I can update the text file with the code below without overwriting the flower_quantity.
def feature_4(flower_file='flowers.txt'):
flower_update = input("Enter the name of the flower you wish to change the price:"
"Lily, Rose, Tulip, Iris, Daisy, Orchid, Dahlia, Peony")
flower_new_price = input("Enter the updated price of the flower")
flower, price = [], []
with open(flower_file) as amend_price:
for line in amend_price:
spt = line.strip().split(",")
flower_price = int(spt[1])
flower_name = str(spt[0])
if flower_name == flower_update :
price.append(flower_new_price)
else:
price.append(flower_price)
flower.append(flower_name)
with open(flower_file, "w") as f_:
for i, v in enumerate(flower):
f_.write("{},{}\n".format(v, str(price[i])))
print("The new price of", flower_update, "is", flower_new_price)
with open(path, 'a') will open your file in append mode, which will not delete contents and put the caret at end of file, so everything will be added at end of file.
You can find many reviews of all available file-opening modes, for example https://stackabuse.com/file-handling-in-python/
There are a couple of ways to get this one done.
But following the way you have already been doing it, you could just include quantity when reading the file. The code would look a little like this.
def feature_4(flower_file='flowers.txt'):
flower_update = input("Enter the name of the flower you wish to change the price:"
"Lily, Rose, Tulip, Iris, Daisy, Orchid, Dahlia, Peony")
flower_new_price = input("Enter the updated price of the flower")
flower, price, quantity = [], [], []
with open(flower_file) as amend_price:
for line in amend_price:
spt = line.strip().split(",")
flower_price = int(spt[1])
flower_name = str(spt[0])
quantity.append(str(spt[2]))
if flower_name == flower_update :
price.append(flower_new_price)
else:
price.append(flower_price)
flower.append(flower_name)
with open(flower_file, "w") as f_:
for i, v in enumerate(flower):
f_.write("{},{},{}\n".format(v, str(price[i]),quantity[i]))
print("The new price of", flower_update, "is", flower_new_price)
Alternatively if you did want to update and not overwrite the entire file, you would need to open the file with open('txtfile.txt','a+'). and navigate to the specified line that you would like to append.
Open the file in append mode
with open(flower_file,"a+"):
the + sign creates a new file if the file is not already present
this will append the file from its last written point. To append from a new line, you should start with \n

Add input to an existing row in csv in python 3.6

I am working in python 3.6 on the following structure:
import csv
aircraft = input("Please insert the aircraft type : ")
characteristics = input("Please insert the respective aircraft characteristics: ")
with open("aircraft_list.csv","a",newline="") as output:
if aircraft not in open("aircraft_list.csv").read():
wr = csv.writer(output)
wr.writerow([aircraft + "," + characteristics])
# with squared brackets since otherwise each letter written as a separate string to the csv, separated by comma
else:
for row in enumerate(output):
data = row.split(",")
if data[0] == aircraft:
wr = csv.writer(output)
wr.writerow([characteristics],1)
I want to write the inputs to a csv in the following format:
B737,Boeing,1970, etc
A320,Airbus,EU, etc
As long as the aircraft e.g. B737 entry does yet not exist, it is easy to write it to a csv. However, as soon as the B737 property already exists in the csv, I want to add the characteristics (not the aircraft) to the entry already made for the e.g. B737. The order of the characteristics does not matter.
I want the additional input characteristics to be added to the correct row in my csv. How would I do that?
Since I’m new to coding I tried the basics and combined it with code which I found on Stackoverflow but unfortunately I cannot get it working.
Your help would be great, thank you!

How can I create an average from a text file in Python 3.5.2?

I've been struggling with this for two days now and I can't seem to find any help. I need to search the file for a student ID (1001 is my test ID being used) and then add the numbers in each line that takes place below each occurrence of the student ID together in order to get an average.
filename = input("Enter file name: \n"
"Example: Grade Data.txt \n")
myFile = open(filename, "r")
selectSID = input("Enter SID: \n")
gradesNum = myFile.read().count(selectSID)
grades = myFile.read()
gradetotal = sum()
average = (gradetotal/gradesNum)
print(average)
The text file that is being opened looks like this:
1001
95
1002
99
1001
96
1002
0
1001
84
1002
25
1001
65
1002
19
This looks like homework so I don't want to write the code for you but here is a pseudo code (there are multiple ways to achieve what you want, this is just a simple beginner level code):
Open file to read
get two lines from the file
is the line1 interesting to me?
yes -> store value from line2 in an array
no -> ignore line2
close file
get average
Some useful references:
Python I/O
Powerful things in python to help with I/O
Built-in functions to help with basic operations like sum
from collections import defaultdict
# with open('filename') as f:
# file = [for i in f]
# in this case, it's the list below
file = [1001,95,1002,99,1001,96,1002,0,1001,84,1002,25,1001,65,1002,19]
infos = defaultdict(list)
sids = file[::2] # select sid info
grades = file[1::2] # select grade info
for sid,grade in zip(sids,grades):
infos[sid].append(grade)
print(infos[1001])
print(infos[1002])
out:
[95, 96, 84, 65]
[99, 0, 25, 19]
in this point, you can sum, average, max or min whatever you want.
Please don't use this code for your homework (use #Aditya's method); you need to learn the basics before using fancy libraries. However, I just learned about collections.defaultdict and I wanted to use it. Watch this video for a great demo on defaultdict.
import collections
import statistics
# This little guy will hold all of our grades
# https://youtu.be/lyDLAutA88s is a great video using it
grades = collections.defaultdict(list)
def get_next_num(file):
"""get the next line of a file,
remove any whitespace surrounding it,
and turn it into an integer"""
return int(next(file).strip())
with open('tmp.txt') as myfile:
while True:
try:
# seriously, watch the video
grades[get_next_num(myfile)].append(get_next_num(myfile))
except StopIteration: # end of file
break
student_id = int(input('Enter student ID. Choices: {} : '.format(list(grades.keys()))))
print(statistics.mean(grades[student_id]))
Updated Answer:
Okay, so I think I understand your question now... Same thing, except I suggest using a list, and as long as the file stays in the same format (SID, Score, so on...), this should work, and requires minimal understanding of Python (i.e No weird libraries like glob):
filename = input("Enter file name: \n"
"Example: Grade Data.txt \n")
myFile = open(filename, "r")
selectSID = input("Enter SID: \n")
raw = myFile.read() ## Raw contents of file.
val = raw.count( selectSID ) ## Returns number of occurences
print( "Occurrences: ", val ) ## Or do something else...
lines = raw.split("\n") ## Create a list containing each new line
scores = [] ## A list that will contain all your scores
while selectSID in lines:
val = lines.index( selectSID ) ## Returns where it is in the list,
score = lines[ val+1 ] ## Gets the item at that position (index) Because the score is one line after the SID
scores.append( int(score) ) ## Adds the score to the list. --Suggest you look into how to safely capturing "int"s (try, except, etc) so the program doesn't crash if the score isn't a number (Advance)
lines.remove( selectSID ) ## automatically removes first occurrence of the SID (cause that's the one we just used)
avg = sum(scores) / len(scores) ## sum() function is self explanatory (takes a list or tuple [a sequence] and adds all values (must be all numbers), THEN len() is just length.
This will return an integer, or with your file, will print:
Occurrences: 4
Regardless if this answered your question, my tip for learning basics is understanding file types and what they can do.
In your case, you will mainly need to focus on strings (text) and integers (whole numbers). Using Pythons IDLE, declare a variable, and type the name and a dot, and use tab to scroll through each functions available.
Example:
>>> myString = "Hello World"
>>> myString.[TAB] #--> [Context Menu Here]
Once you pick one form the list, enter an opening parenthesis "(", and it will give a brief description of what it does.
Hope that helps, and sorry for the lengthy reply (I was trying to explain and give pointers (tips) since you said you were a noob)

find key in dictionary and print value

Hello everyone I am stuck on a class assignment and not sure where to go at this point as my college does not offer tutors for the programming field as this is the first semester that this has been offered. Assignment is:
Write a program that:
Prints out the toy name for that code in a useful message such as, ‘The toy for that code is a Baseball’
The program exits when instead of a toy code, the user enters ‘quit’
below is a sample of the text file that the dict is suppose to populate from
D1,Tyrannasaurous
D2,Apatasauros
D3,Velociraptor
D4,Tricerotops
D5,Pterodactyl
T1,Diesel-Electric
T2,Steam Engine
T3,Box Car
and what I have gotten so far is:
**
fin=open('C:/Python34/Lib/toys.txt','r')
print(fin)
toylookup=dict() #creates a dictionary named toy lookup
def get_line(): #get a single line from the file
newline=fin.readline() #get the line
newline=newline.strip() #strip away extra characters
return newline
print ('please enter toy code here>>>')
search_toy_code= input()
for toy_code in toylookup.keys():
if toy_code == search_toy_code:
print('The toy for that code is a','value')
else:
print("toy code not found")
**
and to be honest I am not even sure I am right with what I have. any help at all would be greatly appreciate thank you.
There are two issues.
Your dictionary isn't getting populated; however there currently isn't enough info in your question to help with that problem. Need to know what the file looks like, etc.
Your lookup loop won't display the values for keys that match. Below is the solution for that.
Try iterating over key:value pairs like this:
for code, toy in toylookup.items():
if key == search_toy_code:
print('The toy for that code ({}) is a {}'.format(code, toy))
else:
print("Toy code ({}) not found".format(code))
Take a look at the docs for dict.items():
items():
Return a new view of the dictionary’s items ((key, value) pairs).
You should make yourself familiar with basic python programming. In order to solve such tasks you need to know about basic data structures and loops.
# define path and name of file
filepath = "test.txt" # content like: B1,Baseball B2,Basketball B3,Football
# read file data
with open(filepath) as f:
fdata = f.readlines() # reads every line in fdata
# fdata is now a list containing each line
# prompt the user
print("please enter toy code here: ")
user_toy_code = input()
# dict container
toys_dict = {}
# get the items with toy codes and names
for line in fdata: # iterate over every line
line = line.strip() # remove extra whitespaces and stuff
line = line.split(" ") # splits "B1,Baseball B2,Basketball"
# to ["B1,Baseball", "B2,Basketball"]
for item in line: # iterate over the items of a line
item = item.split(",") # splits "B1,Baseball"
# to ["B1", "Baseball"]
toys_dict[item[0]] = item[1] # saves {"B1": "Baseball"} to the dict
# check if the user toy code is in our dict
if user_toy_code in toys_dict:
print("The toy for toy code {} is: {}".format(user_toy_code, toys_dict[user_toy_code]))
else:
print("Toy code {} not found".format(user_toy_code))

Categories