Merge branch 'main' of https://gogs.gtsplab.com:5432/SVIG/python-bootcamp
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
# Question 8: It assumes that the CSV file being read
|
||||||
|
# (tomato_sales_error.csv) has a column named "Tomato_Sales."
|
||||||
|
# If the column doesn't exist in the CSV file or if there is an issue
|
||||||
|
# with the file itself, an error will be raised.
|
||||||
|
|
||||||
|
# Question 9:
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
def read_tomato_sales(file_name):
|
||||||
|
data = pd.read_csv(file_name)
|
||||||
|
|
||||||
|
# Ensure required columns exist
|
||||||
|
required_columns = ["Store", "Region", "Tomato_Sales"]
|
||||||
|
missing_columns = set(required_columns) - set(data.columns)
|
||||||
|
if missing_columns:
|
||||||
|
raise ValueError(f"Invalid CSV format: Missing columns: {', '.join(missing_columns)}")
|
||||||
|
|
||||||
|
# Validate Tomato_Sales column
|
||||||
|
tomato_sales = data["Tomato_Sales"]
|
||||||
|
if not tomato_sales.dtype == int and not tomato_sales.dtype == float:
|
||||||
|
raise ValueError("Invalid CSV format: 'Tomato_Sales' column must contain numerical values.")
|
||||||
|
|
||||||
|
# Calculate total tomato sales
|
||||||
|
total_sales = tomato_sales.sum()
|
||||||
|
print(f"Total tomato sales: {total_sales}")
|
||||||
|
|
||||||
|
# Question 10: Bytes represent raw binary data, while strings represent
|
||||||
|
# textual data. Using bytes allows us to handle various character
|
||||||
|
# encodings. By working with bytes, we can ensure that the data remains in
|
||||||
|
# its raw encoded form, allowing for accurate handling of different
|
||||||
|
# encodings.
|
||||||
|
|
||||||
|
# In the interactive Python REPL (Read-Eval-Print Loop), the "_" variable
|
||||||
|
# is a special variable that is automatically assigned the result of the
|
||||||
|
# last expression evaluated. The type of the "_" variable reflects the
|
||||||
|
# type of the last expression evaluated in the REPL.
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
# 1. Annotate the following python expressions with the specific types of each literal, as well as the overall return value:
|
||||||
|
# i = 3
|
||||||
|
# f = 3.0
|
||||||
|
# c = 3+3j
|
||||||
|
# b = b'abcdefg'
|
||||||
|
# s = 'abcdefg'
|
||||||
|
# s = "abcdefg"
|
||||||
|
|
||||||
|
i = 3
|
||||||
|
f = 3.0
|
||||||
|
c = 3+3j
|
||||||
|
b = b'abcdefg'
|
||||||
|
s1 = 'abcdefg'
|
||||||
|
s2 = "abcdefg"
|
||||||
|
|
||||||
|
def check_the_datatype():
|
||||||
|
print()
|
||||||
|
print('This is the answer for Q1:')
|
||||||
|
print()
|
||||||
|
variable_names = ['i', 'f', 'c', 'b', 's1', 's2']
|
||||||
|
data_list = [i, f, c, b, s1, s2]
|
||||||
|
for variable, data in zip(variable_names, data_list):
|
||||||
|
print("The type of this assigned value {} = {} is: {}".format(variable, data, type(data).__name__))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 2. For each of the types string, bytestring, integer, floating point, and imaginary literals,
|
||||||
|
# construct a 5x5 table showing what happens when the character "0" or number 0 is compared to each other type
|
||||||
|
|
||||||
|
from tabulate import tabulate
|
||||||
|
from termcolor import colored
|
||||||
|
|
||||||
|
from tabulate import tabulate
|
||||||
|
from termcolor import colored
|
||||||
|
|
||||||
|
def tablesQ2():
|
||||||
|
print()
|
||||||
|
print('-' * 20)
|
||||||
|
print()
|
||||||
|
print('This is the answer for Q2:')
|
||||||
|
print()
|
||||||
|
types = ["String", "Byte String", "Integer", "Floating Point", "Imaginary"]
|
||||||
|
literals = ['"0"', 'b"0"', '0', '0.0', '0j']
|
||||||
|
|
||||||
|
table_data = []
|
||||||
|
|
||||||
|
for type_ in types:
|
||||||
|
|
||||||
|
row = [type_]
|
||||||
|
|
||||||
|
for literal in literals:
|
||||||
|
|
||||||
|
if type_ == "String":
|
||||||
|
result = literal == '"0"'
|
||||||
|
elif type_ == "Byte String":
|
||||||
|
result = literal.encode() == b"0"
|
||||||
|
elif type_ == "Integer":
|
||||||
|
try:
|
||||||
|
result = int(literal) == 0
|
||||||
|
except ValueError:
|
||||||
|
result = False
|
||||||
|
elif type_ == "Floating Point":
|
||||||
|
try:
|
||||||
|
result = float(literal) == 0.0
|
||||||
|
except ValueError:
|
||||||
|
result = False
|
||||||
|
elif type_ == "Imaginary":
|
||||||
|
result = literal.replace('j', 'j0') == "0j"
|
||||||
|
color = 'green' if result else 'red'
|
||||||
|
colored_result = colored(result, color)
|
||||||
|
row.append(colored_result)
|
||||||
|
|
||||||
|
table_data.append(row)
|
||||||
|
|
||||||
|
table = tabulate(table_data, headers=["Type"] + literals, tablefmt="pipe")
|
||||||
|
print(table)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 3. Now do the same thing for the + and == operators for each pair of types in two other 5x5 tables.
|
||||||
|
|
||||||
|
def tablesQ3():
|
||||||
|
print()
|
||||||
|
print('-' * 20)
|
||||||
|
print()
|
||||||
|
print('This is the answer for Q3:')
|
||||||
|
print()
|
||||||
|
|
||||||
|
operators = ["+", "=="]
|
||||||
|
types = ["str", "bytes", "int", "float", "complex"]
|
||||||
|
literals = ['"0"', 'b"0"', '0', '0.0', '0+0j']
|
||||||
|
|
||||||
|
for operator in operators:
|
||||||
|
print(f"Table for {operator} Operator:")
|
||||||
|
table_data = []
|
||||||
|
|
||||||
|
for type_ in types:
|
||||||
|
row = [type_]
|
||||||
|
|
||||||
|
for literal in literals:
|
||||||
|
try:
|
||||||
|
result = eval(f"{literal} {operator} {type_}({literal})")
|
||||||
|
color = 'green'
|
||||||
|
except TypeError:
|
||||||
|
result = False
|
||||||
|
color = 'red'
|
||||||
|
|
||||||
|
colored_result = colored(result, color)
|
||||||
|
row.append(colored_result)
|
||||||
|
|
||||||
|
table_data.append(row)
|
||||||
|
|
||||||
|
table = tabulate(table_data, headers=["Type"] + literals, tablefmt="pipe")
|
||||||
|
print(table)
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Write a small program that uses the AST module to open the lexer/parser example, and dumps the resulting AST.
|
||||||
|
# See if there are any arguments to the parse method which make the output easier to read.
|
||||||
|
|
||||||
|
# By default, ast.dump() prints the AST in a compact format.
|
||||||
|
# However, there are two optional arguments that can enhance the readability:
|
||||||
|
# indent: Specifies the number of spaces to use for indentation. Setting it to a positive integer (e.g., 4) indents each level of the AST by that amount.
|
||||||
|
# annotate_fields: When set to True, adds field names as comments to the output, making it easier to identify each part of the AST.
|
||||||
|
|
||||||
|
import ast
|
||||||
|
|
||||||
|
def dump_ast(filename):
|
||||||
|
with open(filename, 'r') as file:
|
||||||
|
source_code = file.read()
|
||||||
|
|
||||||
|
try:
|
||||||
|
tree = ast.parse(source_code)
|
||||||
|
ast_dump = ast.dump(tree, indent=4, annotate_fields=True)
|
||||||
|
print(ast_dump)
|
||||||
|
except SyntaxError as e:
|
||||||
|
print(f"Syntax error in {filename}: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
check_the_datatype()
|
||||||
|
tablesQ2()
|
||||||
|
tablesQ3()
|
||||||
|
print()
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
class Tokens(Enum):
|
||||||
|
QUOTE = 1,
|
||||||
|
CHAR = 2,
|
||||||
|
NEWLINE = 3,
|
||||||
|
SPACE = 4
|
||||||
|
|
||||||
|
class Lexer:
|
||||||
|
tokens = list()
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
def lex(self, str):
|
||||||
|
for c in str:
|
||||||
|
if c == "'" or c == '"':
|
||||||
|
self.tokens.append(Tokens.QUOTE)
|
||||||
|
print("Token: QUOTE")
|
||||||
|
elif c == "\n":
|
||||||
|
self.tokens.append(Tokens.NEWLINE)
|
||||||
|
print("Token: NEWLINE")
|
||||||
|
elif c == " ":
|
||||||
|
self.tokens.append(Tokens.SPACE)
|
||||||
|
print("Token: SPACE")
|
||||||
|
else:
|
||||||
|
self.tokens.append(Tokens.CHAR)
|
||||||
|
print("Token: CHAR")
|
||||||
|
def __str__(self):
|
||||||
|
return ",".join(Tokens(token).name for token in self.tokens)
|
||||||
|
|
||||||
|
class States(Enum):
|
||||||
|
INITIAL = 0,
|
||||||
|
BEGINQUOTE = 1
|
||||||
|
|
||||||
|
class Parser:
|
||||||
|
def __init__(self):
|
||||||
|
self.state = States.INITIAL
|
||||||
|
self.line = 1
|
||||||
|
|
||||||
|
def transition(self, state):
|
||||||
|
print(f"{States(self.state).name} -> {States(state).name}")
|
||||||
|
self.state = state
|
||||||
|
|
||||||
|
def parse(self, tokens):
|
||||||
|
for token in tokens:
|
||||||
|
if self.state == States.INITIAL:
|
||||||
|
if token == Tokens.QUOTE:
|
||||||
|
self.transition(States.BEGINQUOTE)
|
||||||
|
elif token == Tokens.NEWLINE:
|
||||||
|
self.line += 1
|
||||||
|
continue
|
||||||
|
if self.state == States.BEGINQUOTE:
|
||||||
|
if token == Tokens.QUOTE:
|
||||||
|
self.transition(States.INITIAL)
|
||||||
|
elif token == Tokens.CHAR or token == Tokens.SPACE:
|
||||||
|
pass
|
||||||
|
elif token == Tokens.NEWLINE:
|
||||||
|
raise ValueError(f"Unterminated string on line {self.line}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test1 = """abcdefg
|
||||||
|
"abcde
|
||||||
|
'a'
|
||||||
|
bareword
|
||||||
|
"""
|
||||||
|
|
||||||
|
lexer = Lexer()
|
||||||
|
lexer.lex(test1)
|
||||||
|
# print(lexer)
|
||||||
|
parser = Parser()
|
||||||
|
try:
|
||||||
|
parser.parse(lexer.tokens)
|
||||||
|
except ValueError as error:
|
||||||
|
print(error)
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user