Create variables from text file in Python - python

This is linked to this question here I used the first answer, I tried changing the code but it didn't seem to work as that example has "[]" in the variables
I have a text file here:
room1North = CP
room1East = CP
room1South = OP
room1West = OP
room2North = OP
room2East = CP
room2South = EP
room2West = OP
I would like Python to create variables with the values in the text file so the variable "room1North = CP" in Python
I have the following code so far
with open("maze files.txt", "r") as f:
data = f.readlines()
room1North, room1East, room1South, room1West, room2North, room2Eeast, room2South, room2West = [d.split('=')[1].split('\n')[0] for d in data]
I get the following error:
IndexError: list index out of range

You don't actually want separate variables; you want a single dict whose keys are read from the file.
with open("maze files.txt", "r") as f:
data = {k:v for k, v in [line.strip().replace(' ', '').split("=") for line in f]}
# data["room1North"] == "CP"
# data["room1East"] == "CP"
# data["room1South"] == "OP"
# etc

Change your code as bellow
with open("maze files.txt", "r") as f:
data = f.readlines()
room1North, room1East, room1South, room1West, room2North, room2Eeast, room2South, room2West = [d.split('=')[1].split('\n')[0] for d in ''.join(data).split('\n')]

I think you'd have more luck using a dictionary rather than relying on pure variables.
with open("maze files.txt", "r") as f:
data = f.readlines()
rooms = {}
for i in data:
currentRoom = i.replace(' ', '').strip().split('=')
rooms[currentRoom[0]] = currentRoom[1]
What you'll be left with is a dictionary like the following
print(rooms)
#{'room1North ': ' CP', 'room1East ': ' CP', 'room1South ': ' OP', 'room1West ': ' OP', 'room2North ': ' OP', 'room2East ': ' CP', 'room2South ': ' EP', 'room2 West ': ' OP'}
You can reference each room and it's value by rooms["room1North"]

Related

Create Dict from Text File + Python:TypeError: 'str' object does not support item assignment

Trying to create a dict from this piece of text:
game_name: Adventure 1
game_goal: Find the magic helmet and bring it to Hans.
game_goalloc: 8
game_goalobj: helmet
game_start: 4
game_xsize: 3
game_ysize: 3
Read in as "config.txt", keep getting a Type Error: 'str' object does not support item assignment.
Can't for the life of me figure out why as doing the exact same operation elsewhere in my code... HELLLP
with open('config.txt') as f:
lines = f.readlines()
for line in lines:
line = line.strip()
if "game_" in line:
game = line.split('_')[-1]
k = game.split(':')[0]
v = game.split(':')[-1]
print(k)
print(v)
game[k] = {}
game[k] = v
created a empty dictionary game_dict = {} and updated it.
with open('game1.txt') as f:
lines = f.readlines()
game_dict = {}
for line in lines:
line = line.strip()
if "game_" in line:
game = line.split('_')[-1]
k = game.split(':')[0]
game_dict[k] = ""
v = game.split(':')[-1]
game_dict[k] = v
print(game_dict)
Output
{'name': ' Adventure 1', 'goal': ' Find the magic helmet and bring it to Hans.', 'goalloc': ' 8', 'goalobj': ' helmet', 'start': ' 4', 'xsize': ' 3', 'ysize': ' 3'}
game = line.split('_')[-1]
k = game.split(':')[0]
v = game.split(':')[-1]
print(k)
print(v)
game[k] = {}
game[k] = v
in the last two lines of codes, you are trying to assign the "game", a str object, with empty {} and then v. this results in the error.
lines = """
game_name: Adventure 1
game_goal: Find the magic helmet and bring it to Hans.
game_goalloc: 8
game_goalobj: helmet
game_start: 4
game_xsize: 3
game_ysize: 3
""".strip().splitlines()
game_dict = {}
for line in lines:
line = line.strip()
if "game_" in line:
game = line.split('_')[-1]
k = game.split(':')[0].strip()
v = game.split(':')[-1].strip()
print(k)
print(v)
game_dict[k] = {}
game_dict[k] = v
print(game_dict)
Maybe this is what you want.
Thanks! Yes - I figured that out just after posting.
I was initializing the dict variable as game and then using the same var within the loop. Silly mistake...
Here is my fixed code:
game = {}
map = {}
#need to update location variable here when a move is made
character = {'inventory': [], 'location': 1}
with open('game1.txt') as f:
lines = f.readlines()
for line in lines:
line = line.strip()
if "game_" in line:
split = line.split('_')[-1]
k,v = split.split(':')
game[k] = v

Data generation Python

I'm trying to generate a dataset based on an existing one, I was able to implement a method to randomly change the contents of files, but I can’t write all this to a file. Moreover, I also need to write the number of changed words to the file, since I want to use this dataset to train a neural network, could you help me?
Input: files with 2 lines of text in each.
Output: files with 3(maybe) lines: the first line does not change, the second changes according to the method, the third shows the number of words changed (if for deep learning tasks it is better to do otherwise, I would be glad to advice, since I'm a beginner)
from random import randrange
import os
Path = "D:\corrected data\\"
filelist = os.listdir(Path)
if __name__ == "__main__":
new_words = ['consultable', 'partie ', 'celle ', 'également ', 'forte ', 'statistiques ', 'langue ',
'cadeaux', 'publications ', 'notre', 'nous', 'pour', 'suivr', 'les', 'vos', 'visitez ', 'thème ', 'thème ', 'thème ', 'produits', 'coulisses ', 'un ', 'atelier ', 'concevoir ', 'personnalisés ', 'consultable', 'découvrir ', 'fournit ', 'trace ', 'dire ', 'tableau', 'décrire', 'grande ', 'feuille ', 'noter ', 'correspondant', 'propre',]
nb_words_to_replace = randrange(10)
#with open("1.txt") as file:
for i in filelist:
# if i.endswith(".txt"):
with open(Path + i,"r",encoding="utf-8") as file:
# for line in file:
data = file.readlines()
first_line = data[0]
second_line = data[1]
print(f"Original: {second_line}")
# print(f"FIle: {file}")
second_line_array = second_line.split(" ")
for j in range(nb_words_to_replace):
replacement_position = randrange(len(second_line_array))
old_word = second_line_array[replacement_position]
new_word = new_words[randrange(len(new_words))]
print(f"Position {replacement_position} : {old_word} -> {new_word}")
second_line_array[replacement_position] = new_word
res = " ".join(second_line_array)
print(f"Result: {res}")
with open(Path + i,"w") as f:
for line in file:
if line == second_line:
f.write(res)
In short, you have two questions:
How to properly replace line number 2 (and 3) of the file.
How to keep track of number of words changed.
How to properly replace line number 2 (and 3) of the file.
Your code:
with open(Path + i,"w") as f:
for line in file:
if line == second_line:
f.write(res)
Reading is not enabled. for line in file will not work. fis defined, but file is used instead. To fix this, do the following instead:
with open(Path + i,"r+") as file:
lines = file.read().splitlines() # splitlines() removes the \n characters
lines[1] = second_line
file.writelines(lines)
However, you want to add more lines to it. I suggest you structure the logic differently.
How to keep track of number of words changed.
Add varaible changed_words_count and increment it when old_word != new_word
Resulting code:
for i in filelist:
filepath = Path + i
# The lines that will be replacing the file
new_lines = [""] * 3
with open(filepath, "r", encoding="utf-8") as file:
data = file.readlines()
first_line = data[0]
second_line = data[1]
second_line_array = second_line.split(" ")
changed_words_count = 0
for j in range(nb_words_to_replace):
replacement_position = randrange(len(second_line_array))
old_word = second_line_array[replacement_position]
new_word = new_words[randrange(len(new_words))]
# A word replaced does not mean the word has changed.
# It could be replacing itself.
# Check if the replacing word is different
if old_word != new_word:
changed_words_count += 1
second_line_array[replacement_position] = new_word
# Add the lines to the new file lines
new_lines[0] = first_line
new_lines[1] = " ".join(second_line_array)
new_lines[2] = str(changed_words_count)
print(f"Result: {new_lines[1]}")
with open(filepath, "w") as file:
file.writelines(new_lines)
Note: Code not tested.

Import CSV File and Doing arithmetic Opertions without importing any Library in PYTHON

My CSV file Looks Like this
Time_stamp; Mobile_number; Download; Upload; Connection_start_time; Connection_end_time; location
1/2/2020 10:43:55;+917777777777;213455;2343;1/2/2020 10:43:55;1/2/2020 10:47:25;09443
1/3/2020 10:33:10;+919999999999;345656;3568;1/3/2020 10:33:10;1/3/2020 10:37:20;89442
1/4/2020 11:47:57;+919123456654;345789;7651;1/4/2020 11:11:10;1/4/2020 11:40:22;19441
1/5/2020 11:47:57;+919123456543;342467;4157;1/5/2020 11:44:10;1/5/2020 11:59:22;29856
1/6/2020 10:47:57;+917777777777;213455;2343;1/6/2020 10:43:55;1/6/2020 10:47:25;09443
MY Question is
Without importing any Library file
How i can read a CSV file & user have to enter the Mobile number & Program should show the Data usage of that number. ie: Arithmetic Operation (Adding Uplink & downlink ) & get the result (Total Data Used)of that specific Mobile number.
Here is what my code looks Like. ( i don't want to import any Pandas Library. )
import pandas as pd
df = pd.read_csv('test.csv', sep=';')
df.columns = [col.strip() for col in df.columns]
usage = df[['Download', 'Upload']][df.Mobile_number == +917777777777].sum().sum()
print(usage)
I'd use csv.DictReader
In [30]: with open('x', 'r') as f:
...: r = csv.DictReader(f, delimiter=';')
...: dct = {}
...: for row in r:
...: dct.setdefault(row[' Mobile_number'], []).append(row)
...:
In [31]: dct
Out[31]:
{'+917777777777': [OrderedDict([('Time_stamp', '1/2/2020 10:43:55'),
(' Mobile_number', '+917777777777'),
(' Download', '213455'),
(' Upload', '2343'),
(' Connection_start_time', '1/2/2020 10:43:55'),
(' Connection_end_time', '1/2/2020 10:47:25'),
(' location', '09443')]),
OrderedDict([('Time_stamp', '1/6/2020 10:47:57'),
(' Mobile_number', '+917777777777'),
(' Download', '213455'),
(' Upload', '2343'),
(' Connection_start_time', '1/6/2020 10:43:55'),
(' Connection_end_time', '1/6/2020 10:47:25'),
(' location', '09443')])],
'+919999999999': [OrderedDict([('Time_stamp', '1/3/2020 10:33:10'),
(' Mobile_number', '+919999999999'),
(' Download', '345656'),
(' Upload', '3568'),
(' Connection_start_time', '1/3/2020 10:33:10'),
(' Connection_end_time', '1/3/2020 10:37:20'),
(' location', '89442')])],
'+919123456654': [OrderedDict([('Time_stamp', '1/4/2020 11:47:57'),
(' Mobile_number', '+919123456654'),
(' Download', '345789'),
(' Upload', '7651'),
(' Connection_start_time', '1/4/2020 11:11:10'),
(' Connection_end_time', '1/4/2020 11:40:22'),
(' location', '19441')])],
'+919123456543': [OrderedDict([('Time_stamp', '1/5/2020 11:47:57'),
(' Mobile_number', '+919123456543'),
(' Download', '342467'),
(' Upload', '4157'),
(' Connection_start_time', '1/5/2020 11:44:10'),
(' Connection_end_time', '1/5/2020 11:59:22'),
(' location', '29856')])]}
In [32]:
You then process list of dict for a given mobile number by something like usage = sum(float(_[' Download']) + float(_[' Upload']) for _ in dct['+91777777777'])
Noting that you specifically wanted to avoid importing any libraries (I assume this means you want to avoid importing even from the included modules) - for a trivial file (I named one supermarkets.csv, the content looks like this):
ID,Address,City,State,Country,Name,Employees
1,3666 21st St,San Francisco,CA 94114,USA,Madeira,8
2,735 Dolores St,San Francisco,CA 94119,USA,Bready Shop,15
3,332 Hill St,San Francisco,California 94114,USA,Super River,25
4,3995 23rd St,San Francisco,CA 94114,USA,Ben's Shop,10
5,1056 Sanchez St,San Francisco,California,USA,Sanchez,12
6,551 Alvarado St,San Francisco,CA 94114,USA,Richvalley,20
Then you can do something like this:
data = []
with open("supermarkets.csv") as f:
for line in f:
data.append(line)
print(data)
From here you can manipulate your each of the entries in the list using string tools and list comprehensions.
You could try open that does not require any library, to read your file and then iterate through it with readlines. Split the line and check your condition depending on the place in the file your data are.
usage=0
with open('test.csv', 'r') as f:
for line in f.readlines():
try:
line_sp = line.split(';')
if line_sp[1]=='+917777777777':
usage += int(line_sp[2])+int(line_sp[3])
except:
#print(line)
pass
print (usage)
Using no imported modules
# read file and create dict of phone numbers
phone_dict = dict()
with open('test.csv') as f:
for i, l in enumerate(f.readlines()):
l = l.strip().split(';')
if (i != 0):
mobile = l[1]
download = int(l[2])
upload = int(l[3])
if phone_dict.get(mobile) == None:
phone_dict[mobile] = {'download': [download], 'upload': [upload]}
else:
phone_dict[mobile]['download'].append(download)
phone_dict[mobile]['upload'].append(upload)
print(phone_dict)
{'+917777777777': {'download': [213455, 213455], 'upload': [2343, 2343]},
'+919999999999': {'download': [345656], 'upload': [3568]},
'+919123456654': {'download': [345789], 'upload': [7651]},
'+919123456543': {'download': [342467], 'upload': [4157]}}
# function to return usage
def return_usage(data: dict, number: str):
download_usage = sum(data[number]['download'])
upload_usage = sum(data[number]['upload'])
return download_usage + upload_usage
# get user input to return usage
number = input('Please input a phone number')
usage = return_usage(phone_dict, number)
print(usage)
>>> Please input a phone number (numbers only) +917777777777
>>> 431596
A combination of csv and defaultdict can fit your use case:
import csv
from collections import defaultdict
d= defaultdict(list)
with open('data.txt',newline='') as csvfile:
reader = csv.DictReader(csvfile, delimiter=';', skipinitialspace = True)
headers = reader.fieldnames
for row in reader:
row['Usage'] = int(row['Upload']) + int(row['Download'])
d[row.get('Mobile_number')].append(row["Usage"])
print(d)
defaultdict(list,
{'+917777777777': [215798, 215798],
'+919999999999': [349224],
'+919123456654': [353440],
'+919123456543': [346624]})
#get sum for specific mobile number :
sum(d.get("+917777777777"))
431596
Additional details :
new_d = {}
for k,v in d.items():
kb = sum(v)
mb = kb/1024
gb = kb/1024**2
usage = F"{kb}KB/{mb:.2f}MB/{gb:.2f}GB"
new_d[k] = usage
print(new_d)
{'+917777777777': '431596KB/421.48MB/0.41GB',
'+919999999999': '349224KB/341.04MB/0.33GB',
'+919123456654': '353440KB/345.16MB/0.34GB',
'+919123456543': '346624KB/338.50MB/0.33GB'}

Python: Search particular string in file

I have text file, that store orders info in following format. I try to search an order by first line of the block, that represent ID and print 7 next lines. But my code checking just the first line or print all line's that contain an input number. Could somebody help me?
4735
['Total price: ', 1425.0]
['Type of menu: ', 'BBQ']
['Type of service: ', ' ']
['Amount of customers: ', 25.0]
['Discount: ', '5%', '= RM', 75.0]
['Time: ', '2017-01-08 21:39:19']
3647
['Total price: ', 2000.0]
['Type of menu: ', ' ']
['Type of service: ', 'Tent ']
['Amount of customers: ', 0]
.......
I use the following code to search in text file.
try:
f = open('Bills.txt', 'r')
f.close()
except IOError:
absent_input = (raw_input("|----File was not founded----|\n|----Press 'Enter' to continue...----|\n"))
report_module = ReportModule()
report_module.show_report()
Id_input = (raw_input("Enter ID of order\n"))
with open("Bills.txt", "r") as f:
searchlines = f.readlines()
j = len(searchlines) - 1
for i, line in enumerate(searchlines):
if Id_input in str(line): # I also try to check in this way (Id_input == str(line)), but it didn't work
k = min(i + 7, j)
for l in searchlines[i:k]: print l,
print
else:
absent_input = (raw_input("|----Order was not founded----|\n|----Press 'Enter' to continue...----|\n"))
report_module = ReportModule()
report_module.show_report()
check the following code.
Id_input = (raw_input("Enter ID of order\n")).strip()
try:
f = open("Bills.txt", "r")
print_rows = False
for idline in f:
if idline.strip() == Id_input:
print_rows = True
continue
if print_rows:
if idline.startswith("["):
print idline
else:
break
if not print_rows:
absent_input = (raw_input("|----Order was not founded----|\n|---- Press 'Enter' to continue...----|\n"))
report_module = ReportModule()
report_module.show_report()
except IOError:
absent_input = (raw_input("|----File was not founded----|\n|---- Press 'Enter' to continue...----|\n"))
report_module = ReportModule()
report_module.show_report()

Python CSV - use dictionary for each cell

i hope my question makes sense. i am looking for a way to read a csv file, and map a dictionary to each cell. i can make it work without csv, but i am having a hard time making it work when reading a csv file.
note:
string0 would be cell A1 or row[0]
string1 would be cell B1 or row[1]
string2 would be cell C1 or row[2]
this is what i have so far:
dict0 = {'A':'CODE1', 'B':'CODE2'}
text0 = []
string0 = 'A'
dict1 = {'avenue':'ave', 'street':'st', 'road':'rd', 'court':'ct'}
text1 = []
string1 = '123 MAIN AVENUE'
dict2 = {'(':'', ')':'', '-':'', ' ':'', '/':'', '\\':''}
text2 = []
string2 = '(123) 456/7890'
for i in string0:
newcode = dict0.get(i,i)
text0.append(newcode)
print ' '.join(text0)
for i in string1.lower().split(' '):
newaddress = dict1.get(i.lower(),i)
text1.append(newaddress)
print ' '.join(text1)
for i in string2:
newphone = dict2.get(i,i)
text2.append(newphone)
print ''.join(text2)
the code above works exactly as i intend it to work, but im having a hard time trying to make it work when reading a csv file.
thank you very much
edit #1:***********************************************
here is an excerpt of sample1.csv:
A,123 MAIN STREET,(123) 456-7890
B,888 TEST ROAD,(222) 555-5555
sorry if the code isnt much cleaner/clearer, but that is why i am asking for guidance.
in essence, every column will have a dictionary associated with it, so that the "code" column will write "CODE1 or CODE2" depending on the value of cell A1 ("A" or "B").
column 2 will have dict1{} associated with it, and will clean up the address column.
column 3 will have dict2{} associated with it, and will remove (,),/,\ from the phone number column.
my issue is i do not know how to start the code. i can write the code if i set the cell information as variables (see me code above, variables: string0, string1, string2), but i do not know how i would start to iterate the csv file.
thank you
edit #2:***********************************************
here is my code when i try using import csv
dict0 = {'A':'CODE1', 'B':'CODE2'}
text0 = []
dict1 = {'avenue':'ave', 'street':'st', 'road':'rd', 'court':'ct'}
text1 = []
dict2 = {'(':'', ')':'', '-':'', ' ':'', '/':'', '\\':''}
text2 = []
import csv
with open('O:/sample1.csv', 'rb') as c:
reader = csv.reader(c)
for row in reader:
for i in row[0]:
newcode = dict0.get(i,i)
text0.append(newcode)
for i in row[1].lower().split(' '):
newaddress = dict1.get(i.lower(),i)
text1.append(newaddress)
for i in row[2]:
newphone = dict2.get(i,i)
text2.append(newphone)
print str(' '.join(text0)) + ',' + str(' '.join(text1)) + ',' + str(''.join(text2))
prints:
CODE1,123 main st,1234567890
CODE1 CODE2,123 main st 888 test rd,12345678902225555555
i would like to print:
CODE1,123 main st,1234567890
CODE2,888 test rd,2225555555
hopefully someone can help
thank you
edit #3 *********************************************************************************************************************
can the following be improved (syntax, indentation etc..):
sample1.csv:
A,123 MAIN STREET,(123) 456-7890
B,888 TEST ROAD,(222) 555-5555
here is the code:
import csv
newcsv = csv.writer(open('O:/csvfile1.csv', 'ab'))
with open('O:/sample1.csv', 'rb') as c:
reader = csv.reader(c)
dict0 = {'A':'CODE1', 'B':'CODE2'}
dict1 = {'avenue':'ave', 'street':'st', 'road':'rd', 'court':'ct'}
dict2 = {'(':'', ')':'', '-':'', ' ':'', '/':'', '\\':''}
# read element in *reader*
for row in reader:
text0 = []
text1 = []
text2 = []
newline = []
# read element in *row*
for i in row[0]:
newcode = dict0.get(i,i)
text0.append(newcode)
newline.append(' '.join(text0))
for i in row[1].lower().split(' '):
newaddress = dict1.get(i.lower(),i)
text1.append(newaddress)
newline.append(' '.join(text1))
for i in row[2]:
newphone = dict2.get(i,i)
text2.append(newphone)
newline.append(''.join(text2))
newcsv.writerow(newline)
print newline
prints the following:
['CODE1', '123 main st', '1234567890']
['CODE2', '888 test rd', '2225555555']
creates csvfile1.csv (using '|' as a 'cell delimiter') and its exactly what i want:
CODE1|123 main st|1234567890
CODE2|888 test rd|2225555555
just wondering if the above code can be improved/written in an more effective way.
thank you
The reason for the garbled output is that you are not clearing the text<n> variables on each cycle of the loop. While there is the fix below, I recommend reading at least how to define functions, rewriting the code without so many global variables so that you don't run into the same problems like now.
with open('O:/sample1.csv', 'rb') as c:
reader = csv.reader(c)
for row in reader:
text0 = []
text1 = []
text2 = []
for i in row[0]:
newcode = dict0.get(i,i)
text0.append(newcode)
for i in row[1].lower().split(' '):
newaddress = dict1.get(i.lower(),i)
text1.append(newaddress)
for i in row[2]:
newphone = dict2.get(i,i)
text2.append(newphone)
print str(' '.join(text0)) + ',' + str(' '.join(text1)) + ',' + str(''.join(text2))

Categories