Applied Programming/Dictionaries and Sets/Python3
regex_dictionaries.py
editThis is the regex way of using dictionaries.
"""This program demonstrates file, list, and dictionary processing.
It creates a temporary file, adds data to the file, and reads the file
into a list of dictionaries. It then provides a menu of options for displaying
and searching the file data.
It will not run if the file already exists.
Input:
None
Output:
A temporary file and file contents.
References:
https://www.tutorialspoint.com/python/python_tuples.htm
"""
import os
import re
import sys
def create_file(filename):
"""Creates filename and adds temperature data to the file.
Args:
filename (string): Filename to create.
Returns:
None
"""
with open(filename, 'w') as file:
file.write('"C","F"\n')
for c in range(0, 101, 10):
f = c * 9 / 5 + 32
file.write(f"{c:.2} {f:.2}\n")
def read_file(filename):
"""Reads filename and returns a list of temperature tuples.
Args:
filename (string): Filename to open and read.
Returns:
A list of temperature tuples.
Raises:
ValueError: Invalid header format.
ValueError: Invalid record format.
ValueError: No data found.
"""
with open(filename, 'r') as file:
line = file.readline()
if line.strip() != '"C","F"':
raise ValueError(f"Invalid header format found in {filename}: {line}")
temperatures = []
fields = ['C', 'F']
for line in file:
if 'C' in line:
continue
record = re.findall('"(.*?)"', line)
if len(record) != len(fields):
raise ValueError(f"Invalid record format found in {filename}: {line}")
temperature = {}
for i in range(len(fields)):
temperature[fields[i]] = float(record[i])
temperatures.append(temperature)
if len(temperatures) == 0:
raise ValueError(f"No data found in {filename}")
return temperatures
def delete_file(filename):
"""Deletes filename.
Args:
filename (string): Filename to delete.
Returns:
None
"""
os.remove(filename)
def get_choice():
"""Displays menu and gets choice.
Args:
None
Returns:
choice (int) or None
"""
while True:
try:
print("Select from the following options or press <Enter> to quit:")
print("1. Display table sorted by Celsius temperature.")
print("2. Display table sorted by Fahrenheit temperature.")
print("3. Search for Celsius temperature.")
print("4. Search for Fahrenheit temperature.")
choice = input()
choice = int(choice)
if 1 <= choice <= 4:
print()
return choice
print(f"{choice} is not a valid choice.\n")
except ValueError:
if choice == "":
return None
print(f"{choice} is not a valid choice.\n")
def display_temperatures(temperatures, scale):
"""Displays temperatures sorted in scale order.
Args:
temperatures (list of Celsius, Fahrenheit tuples)
scale (string): "Celsius" or "Fahrenheit"
Returns:
None
"""
if scale == "Celsius":
data = sorted(temperatures, key=lambda record: record['C'])
fields = ['C', 'F']
elif scale == "Fahrenheit":
data = sorted(temperatures, key=lambda record: record['F'])
fields = ['F', 'C']
else:
raise ValueError("scale must be Celsius or Fahrenheit")
print(f"{fields[0]} \t {fields[1]})
for record in data:
print(f"{record[fields[0]]} \t {record[fields[1]]}")
print()
def get_temperature(scale):
"""Gets Fahrenheit or Celsius temperature.
Args:
scale (string): "Celsius" or "Fahrenheit"
Returns:
temperature (float) or None
"""
assert scale == "Celsius" or scale == "Fahrenheit"
while True:
try:
print("Enter %s temperature:" % scale)
temperature = input()
temperature = float(temperature)
print()
return temperature
except ValueError:
print("%s is not a valid %s temperature\n" %
(temperature, scale))
return None
def search_temperatures(temperatures, scale):
"""Search temperatures for a scale temperature and display the nearest match.
Args:
temperatures (list of Celsius, Fahrenheit tuples)
scale (string): "Celsius" or "Fahrenheit"
Returns:
None
Raises:
ValueError: If temperatures list is empty
ValueError: If scale is invalid
"""
if len(temperatures) <= 0:
raise ValueError("temperatures list is empty")
temperature = get_temperature(scale)
if temperature == None:
return
if scale == "Celsius":
search_element = 'C'
display_element = 'F'
other_scale = "Fahrenheit"
elif scale == "Fahrenheit":
search_element = 'F'
display_element = 'C'
other_scale = "Celsius"
else:
raise ValueError("scale must be Celsius or Fahrenheit")
data = sorted(temperatures, key=lambda record: record[search_element])
last = data[0]
for record in data:
if temperature < record[search_element]:
break
last = record
if temperature < last[search_element]:
print(f"{temperature:.2}° {scale} is less than {last[display_element]:.2}° {other_scale}\n")
elif temperature == last[search_element]:
print(f"{temperature:.2}° {scale} is {last[display_element]:.2}° {other_scale}\n")
elif temperature > record[search_element]:
print(f"{temperature:.2}° {scale} is greater than {last[display_element]:.2}° {other_scale}\n")
else:
print(f"{temperature:.2}° {scale} is between {last[display_element]:.2}° {other_scale} and {record[display_element]:.2
{other_scale}\n")
def main():
"""Runs the main program logic."""
try:
filename = "~temperatures.txt"
if os.path.isfile(filename):
print(f"File '{filename}' already exists.")
exit(1)
create_file(filename)
temperatures = read_file(filename)
delete_file(filename)
while True:
choice = get_choice()
if choice == None:
break
elif choice == 1:
display_temperatures(temperatures, "Celsius")
elif choice == 2:
display_temperatures(temperatures, "Fahrenheit")
elif choice == 3:
search_temperatures(temperatures, "Celsius")
elif choice == 4:
search_temperatures(temperatures, "Fahrenheit")
else:
raise ValueError("Invalid option selected")
except:
print("Unexpected error.")
print("Error:", sys.exc_info()[1])
print("File: ", sys.exc_info()[2].tb_frame.f_code.co_filename)
print("Line: ", sys.exc_info()[2].tb_lineno)
main()
csv_dictionaries.py
edit"""This program demonstrates file, list, and dictionary processing.
It creates a temporary file, adds data to the file, and reads the file
into a list of dictionaries. It then provides a menu of options for displaying
and searching the file data.
It will not run if the file already exists.
Input:
None
Output:
A temporary file and file contents.
References:
https://www.tutorialspoint.com/python/python_tuples.htm
"""
import os
import csv
import sys
def create_file(filename):
"""Creates filename and adds temperature data to the file.
Args:
filename (string): Filename to create.
Returns:
None
"""
with open(filename, 'w') as file:
file.write('"C","F"\n')
for c in range(0, 101, 10):
f = c * 9 / 5 + 32
file.write(f'"{c:.1f}","{f:.1f}"\n')
def read_file(filename):
"""Reads filename and returns a list of temperature dictionaries.
Args:
filename (string): Filename to open and read.
Returns:
A list of temperature dictionaries.
Raises:
ValueError: Invalid header format.
ValueError: Invalid record format.
ValueError: No data found.
"""
with open(filename, 'r') as file:
temperatures = []
reader = csv.DictReader(file)
for line in reader:
temperatures.append(dict(line))
if len(temperatures) == 0:
raise ValueError(f"No data found in {filename}")
return temperatures
def delete_file(filename):
"""Deletes filename.
Args:
filename (string): Filename to delete.
Returns:
None
"""
os.remove(filename)
def get_choice():
"""Displays menu and gets choice.
Args:
None
Returns:
choice (int) or None
"""
while True:
try:
print("Select from the following options or press <Enter> to" +
" quit:")
print("1. Display table sorted by Celsius temperature.")
print("2. Display table sorted by Fahrenheit temperature.")
print("3. Search for Celsius temperature.")
print("4. Search for Fahrenheit temperature.")
choice = input()
choice = int(choice)
if 1 <= choice <= 4:
print()
return choice
print(f"{choice} is not a valid choice.\n")
except ValueError:
if choice == "":
return None
print(f"{choice} is not a valid choice.\n")
def display_temperatures(temperatures, scale):
"""Displays temperatures sorted in scale order.
Args:
temperatures (list of Celsius, Fahrenheit tuples)
scale (string): "Celsius" or "Fahrenheit"
Returns:
None
"""
if scale == "Celsius":
data = sorted(temperatures, key=lambda record: float(record['C']))
fields = ['C', 'F']
elif scale == "Fahrenheit":
data = sorted(temperatures, key=lambda record: float(record['F']))
fields = ['F', 'C']
else:
raise ValueError("scale must be Celsius or Fahrenheit")
print(f"{fields[0]:10}{fields[1]:10}")
for record in data:
print(f"{record[fields[0]]:10}{record[fields[1]]:10}")
print()
def get_temperature(scale):
"""Gets Fahrenheit or Celsius temperature.
Args:
scale (string): "Celsius" or "Fahrenheit"
Returns:
temperature (float) or None
"""
assert scale == "Celsius" or scale == "Fahrenheit"
while True:
try:
print(f"Enter {scale} temperature:")
temperature = input()
temperature = float(temperature)
print()
return temperature
except ValueError:
print(f"{temperature} is not a valid {scale} temperature\n")
return None
def search_temperatures(temperatures, scale):
"""Search temperatures for a scale temperature and display the nearest match.
Args:
temperatures (list of Celsius, Fahrenheit tuples)
scale (string): "Celsius" or "Fahrenheit"
Returns:
None
Raises:
ValueError: If temperatures list is empty
ValueError: If scale is invalid
"""
if len(temperatures) <= 0:
raise ValueError("temperatures list is empty")
temperature = get_temperature(scale)
if temperature is None:
return
if scale == "Celsius":
search_element = 'C'
display_element = 'F'
other_scale = "Fahrenheit"
elif scale == "Fahrenheit":
search_element = 'F'
display_element = 'C'
other_scale = "Celsius"
else:
raise ValueError("scale must be Celsius or Fahrenheit")
data = sorted(temperatures, key=lambda record:
float(record[search_element]))
last = data[0]
for record in data:
if temperature < float(record[search_element]):
break
last = record
if temperature < float(last[search_element]):
print(f'{temperature}° {scale} is less than' +
f' {last[display_element]}° {other_scale}.')
elif temperature == float(last[search_element]):
print(f'{temperature}° {scale} is {last[display_element]}°' +
f' {other_scale}.')
elif temperature > float(last[search_element]):
print(f'{temperature}° {scale} is greater than' +
f' {last[display_element]}° {other_scale}.')
else:
print(f'{temperature}° {scale} is between {last[display_element]}°' +
f' {other_scale} and {record[display_element]}° {other_scale}.')
def main():
"""Runs the main program logic."""
try:
filename = "~temperatures.txt"
if os.path.isfile(filename):
print("File '%s' already exists." % filename)
os.remove(filename)
create_file(filename)
temperatures = read_file(filename)
delete_file(filename)
while True:
choice = get_choice()
if choice is None:
break
elif choice == 1:
display_temperatures(temperatures, "Celsius")
elif choice == 2:
display_temperatures(temperatures, "Fahrenheit")
elif choice == 3:
search_temperatures(temperatures, "Celsius")
elif choice == 4:
search_temperatures(temperatures, "Fahrenheit")
else:
raise ValueError("Invalid option selected")
except:
os.remove(filename)
print("Unexpected error.")
print("Error:", sys.exc_info()[1])
print("File: ", sys.exc_info()[2].tb_frame.f_code.co_filename)
print("Line: ", sys.exc_info()[2].tb_lineno)
main()
Try It
editCopy and paste the code above into one of the following free online development environments or use your own Python3 compiler / interpreter / IDE.