Compare commits
32
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e72d07462d | ||
|
|
a77fddefc4 | ||
|
|
dd7f954e6c | ||
|
|
b70051c109 | ||
|
|
cb88499ac9 | ||
|
|
f0b8c0fe9d | ||
|
|
caf98f8302 | ||
|
|
33beb1723f | ||
|
|
f5bedf2691 | ||
|
|
74e537e6d1 | ||
|
|
cd52ceb474 | ||
|
|
35ec8040f1 | ||
|
|
245b135a25 | ||
|
|
93817c20d9 | ||
|
|
d5a09ecb17 | ||
|
|
77f2214c3f | ||
|
|
94123d93f0 | ||
|
|
a4d5738583 | ||
|
|
4e3e3fe37e | ||
|
|
9f8c120d8a | ||
|
|
ba730af7cb | ||
|
|
2c113bed43 | ||
|
|
484f1c31e4 | ||
|
|
9445050af1 | ||
|
|
31278dbc6e | ||
|
|
ff270aed61 | ||
|
|
49545ed01b | ||
|
|
d0860db036 | ||
|
|
9d0adc580b | ||
|
|
84f99b0461 | ||
|
|
3eb2fa97a2 | ||
|
|
849f11dfbb |
@@ -1,5 +0,0 @@
|
||||
.DS_Store
|
||||
geckodriver.log
|
||||
.gitignore
|
||||
*.pyc
|
||||
*/__pycache__
|
||||
Vendored
-7
@@ -7,13 +7,6 @@
|
||||
"program": "simulation/SimulationRunner.py",
|
||||
"justMyCode": true,
|
||||
"args": "./HotdogSimulation.py"
|
||||
},
|
||||
{
|
||||
"name": "Python: File",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"justMyCode": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
|
||||
# In[1]:
|
||||
|
||||
|
||||
import requests
|
||||
|
||||
url = 'https://www.sayweee.com/zh/product/Vital-Farms-Pasture-Raised-Eggs--Large-18-count/40709'
|
||||
response = requests.get(url)
|
||||
html_content = response.text
|
||||
html_content
|
||||
|
||||
|
||||
# In[2]:
|
||||
|
||||
|
||||
from lxml import html
|
||||
|
||||
tree = html.fromstring(html_content)
|
||||
script = tree.xpath('//script[@id="__NEXT_DATA__"]/text()')[0]
|
||||
next_data = script.split('__NEXT_DATA__ = ')[1].split(';</script>')[0]
|
||||
|
||||
|
||||
# In[ ]:
|
||||
|
||||
|
||||
import json
|
||||
|
||||
data = json.loads(next_data)
|
||||
price = data['props']['initialState']['pdp']['product']['price']
|
||||
print(price)
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
|
||||
# In[1]:
|
||||
|
||||
|
||||
from google.cloud import pubsub_v1
|
||||
|
||||
|
||||
# In[2]:
|
||||
|
||||
|
||||
# Set the project ID and topic name
|
||||
project_id = "sloetjes-project1"
|
||||
topic_name = "sloetjes-project1"
|
||||
subscription_name = "sloetjes-final-project1"
|
||||
|
||||
|
||||
# In[3]:
|
||||
|
||||
|
||||
# Create a publisher client
|
||||
publisher = pubsub_v1.PublisherClient()
|
||||
|
||||
|
||||
# In[4]:
|
||||
|
||||
|
||||
# Create the fully qualified topic path
|
||||
topic_path = publisher.topic_path(project_id, topic_name)
|
||||
|
||||
|
||||
# In[5]:
|
||||
|
||||
|
||||
# Create the Pub/Sub topic
|
||||
topic = publisher.create_topic(name = topic_path)
|
||||
|
||||
|
||||
# In[ ]:
|
||||
|
||||
|
||||
# Print the topic name
|
||||
print(f"Topic created: {topic.name}")
|
||||
|
||||
|
||||
# In[ ]:
|
||||
|
||||
|
||||
# Create the subscription if it doesn't exist
|
||||
subscription_path = subscriber.subscription_path(project_id, subscription_name)
|
||||
topic_path = publisher.topic_path(project_id, topic_name)
|
||||
|
||||
# Publish a message to the topic
|
||||
message = "Hello, World!"
|
||||
data = message.encode("utf-8")
|
||||
publisher.publish(topic_path, data=data)
|
||||
print(f"Message published: {message}")
|
||||
|
||||
# Pull the message from the subscription
|
||||
response = subscriber.pull(subscription_path, max_messages=1)
|
||||
for received_message in response.received_messages:
|
||||
print(f"Received message: {received_message.message.data}")
|
||||
|
||||
# Acknowledge the message
|
||||
subscriber.acknowledge(subscription_path, [received_message.ack_id])
|
||||
@@ -1,28 +0,0 @@
|
||||
# Question 1:
|
||||
# The international standard for floating-point representation is
|
||||
# called the "IEEE 754 Standard for Floating-Point Arithmetic."
|
||||
|
||||
# Question 2:
|
||||
# 32-bit and 64-bit formats are the most widely used ones in practice.
|
||||
|
||||
# Question 3:
|
||||
# My computer supports all these formats
|
||||
import numpy as np
|
||||
|
||||
supported_formats = np.finfo(np.float32).bits, np.finfo(np.float64).bits
|
||||
print(f"Your computer supports the following floating-point formats: {supported_formats}")
|
||||
|
||||
|
||||
# Question 4:
|
||||
# Using the Pandas multiplication operator (df['Number1'] * df['Number2'])
|
||||
# , the result is automatically converted to a floating-point data type.
|
||||
# On the other hand, when I multiply the numbers using the normal Python
|
||||
# multiplication operator (num1 * num2), the result remains an integer
|
||||
# data type.
|
||||
|
||||
# Question 5:
|
||||
# The size of a floating-point number in memory is primarily determined
|
||||
# by the data type and not the actual value it represents. So the size
|
||||
# of a Python floating-point number does not change as it gets larger.
|
||||
import sys
|
||||
print(sys.getsizeof(70))
|
||||
@@ -1,30 +0,0 @@
|
||||
# Question 7:
|
||||
# 1. Strings in Python are sequences of Unicode characters, while bytes
|
||||
# are sequences of raw binary data.
|
||||
# 2. Strings in Python are immutable, bytes objects are mutable
|
||||
# 3. Strings in Python are encoded using a specific character encoding,
|
||||
# bytes objects do not have an inherent encoding and represent raw binary
|
||||
# data.
|
||||
import sys
|
||||
|
||||
string_example = "Hello"
|
||||
bytes_example = b"Hello"
|
||||
|
||||
string_size = sys.getsizeof(string_example)
|
||||
bytes_size = sys.getsizeof(bytes_example)
|
||||
|
||||
print("Size of string:", string_size)
|
||||
print("Size of bytes:", bytes_size)
|
||||
|
||||
# Emojis are represented using Unicode characters, which require more
|
||||
# bytes to store compared to ASCII characters. Therefore, if you have
|
||||
# a string that contains emojis, its size will be larger than a string
|
||||
# without emojis.
|
||||
|
||||
def print_string_as_numbers(input_string):
|
||||
for char in input_string:
|
||||
print(ord(char), end=' ')
|
||||
|
||||
# Example usage
|
||||
input_string = "Hello, World!"
|
||||
print_string_as_numbers(input_string)
|
||||
@@ -1,36 +0,0 @@
|
||||
# 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.
|
||||
@@ -1 +0,0 @@
|
||||
print('Hi')
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
|
||||
# In[1]:
|
||||
import os
|
||||
from google.cloud import pubsub_v1
|
||||
|
||||
|
||||
# In[2]:
|
||||
# Set the project ID and topic name
|
||||
project_id = 'price-extraction-project'
|
||||
topic_name = 'nfl-zipcodes'
|
||||
|
||||
|
||||
# In[3]:
|
||||
# Create a publisher client
|
||||
publisher = pubsub_v1.PublisherClient()
|
||||
|
||||
|
||||
# In[4]:
|
||||
# Get the topic path
|
||||
topic_path = publisher.topic_path(project_id, topic_name)
|
||||
|
||||
|
||||
# In[5]:
|
||||
# Define the zip codes for all NFL cities
|
||||
nfl_zipcodes = {
|
||||
'Arizona Cardinals': '85305',
|
||||
'Atlanta Falcons': '30363',
|
||||
'Baltimore Ravens': '21230',
|
||||
'Buffalo Bills': '14127',
|
||||
'Carolina Panthers': '28202',
|
||||
'Chicago Bears': '60605',
|
||||
'Cincinnati Bengals': '45202',
|
||||
'Cleveland Browns': '44115',
|
||||
'Dallas Cowboys': '76011',
|
||||
'Denver Broncos': '80204',
|
||||
'Detroit Lions': '48226',
|
||||
'Green Bay Packers': '54304',
|
||||
'Houston Texans': '77054',
|
||||
'Indianapolis Colts': '46225',
|
||||
'Jacksonville Jaguars': '32202',
|
||||
'Kansas City Chiefs': '64129',
|
||||
'Las Vegas Raiders': '89118',
|
||||
'Los Angeles Chargers': '92626',
|
||||
'Los Angeles Rams': '90305',
|
||||
'Miami Dolphins': '33056',
|
||||
'Minnesota Vikings': '55415',
|
||||
'New England Patriots': '02035',
|
||||
'New Orleans Saints': '70112',
|
||||
'New York Giants': '07073',
|
||||
'New York Jets': '07932',
|
||||
'Philadelphia Eagles': '19145',
|
||||
'Pittsburgh Steelers': '15212',
|
||||
'San Francisco 49ers': '95054',
|
||||
'Seattle Seahawks': '98056',
|
||||
'Tampa Bay Buccaneers': '33607',
|
||||
'Tennessee Titans': '37213',
|
||||
'Washington Football Team': '20785'
|
||||
}
|
||||
|
||||
|
||||
# In[6]:
|
||||
# Publish each zip code to the topic
|
||||
for team, zipcode in nfl_zipcodes.items():
|
||||
data = f'{zipcode}'.encode('utf-8')
|
||||
publisher_future = publisher.publish(topic_path, data=data)
|
||||
message_id = publisher_future.result()
|
||||
print(f"message_id = {message_id}")
|
||||
|
||||
print('All zip codes published.')
|
||||
|
||||
|
||||
# In[ ]:
|
||||
import os
|
||||
import time
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.chrome.service import Service
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from google.cloud import pubsub_v1
|
||||
|
||||
# Set the project ID and subscription name
|
||||
project_id = 'price-extraction-project'
|
||||
topic_name = 'nfl-zipcodes'
|
||||
subscription_name = 'sloetjes'
|
||||
|
||||
# Set the path to your ChromeDriver executable
|
||||
chrome_driver_path = "/Users/sloetjeswong/Downloads/chromedriver_mac_arm64/chromedriver"
|
||||
|
||||
# Set up a Google Cloud Pub/Sub subscriber
|
||||
subscriber = pubsub_v1.SubscriberClient()
|
||||
subscription_path = subscriber.subscription_path(project_id, subscription_name)
|
||||
|
||||
# Set up a ChromeDriver instance
|
||||
chrome_options = webdriver.ChromeOptions()
|
||||
chrome_options.add_argument("--headless") # Run Chrome in headless mode
|
||||
chrome_service = Service(chrome_driver_path)
|
||||
chrome_service.start()
|
||||
driver = webdriver.Remote(chrome_service.service_url, options=chrome_options)
|
||||
|
||||
def callback(message):
|
||||
# Get the zip code from the message
|
||||
zip_code = message.data.decode("utf-8")
|
||||
print(f"Received message with zip code: {zip_code}")
|
||||
|
||||
# Open the product page for the rice crackers for the given zip code
|
||||
product_url = f"https://www.sayweee.com/zh/product/Want-Want-Senbei-Rice-Crackers/17119?trace_id=89f7c636-05b8-4f52-abdd-74de3a83f45d&zip={zip_code}"
|
||||
driver.get(product_url)
|
||||
|
||||
# Wait for the price to load
|
||||
price_xpath = "//span[@class='price']"
|
||||
price_element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, price_xpath)))
|
||||
|
||||
# Extract the price and print it
|
||||
price = price_element.text
|
||||
print(f"Price for zip code {zip_code}: {price}")
|
||||
|
||||
# Acknowledge the message
|
||||
message.ack()
|
||||
|
||||
# Subscribe to the topic
|
||||
streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
|
||||
print(f"Listening for messages on {subscription_path}...")
|
||||
streaming_pull_future.result()
|
||||
|
||||
# Keep the script running
|
||||
while True:
|
||||
time.sleep(60)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 130 KiB |
+165
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
|
||||
# In[ ]:
|
||||
|
||||
|
||||
from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime, ForeignKey
|
||||
from sqlalchemy.orm import sessionmaker, relationship, declarative_base
|
||||
from flask import Flask, render_template
|
||||
|
||||
# In[ ]:
|
||||
|
||||
|
||||
# Create a base class for declarative models
|
||||
Base = declarative_base()
|
||||
|
||||
class Product(Base):
|
||||
__tablename__ = 'product'
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String)
|
||||
SKU_PLU_UPC_number = Column(String)
|
||||
price_histories = relationship("PriceHistory", back_populates="product")
|
||||
|
||||
class Retailer(Base):
|
||||
__tablename__ = 'retailer'
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String)
|
||||
products = relationship("Product", secondary="retailer_product")
|
||||
|
||||
class Price(Base):
|
||||
__tablename__ = 'price'
|
||||
id = Column(Integer, primary_key=True)
|
||||
MOQ = Column(Integer)
|
||||
price = Column(Float)
|
||||
|
||||
class ScraperJob(Base):
|
||||
__tablename__ = 'scraper_job'
|
||||
id = Column(Integer, primary_key=True)
|
||||
start_time = Column(DateTime)
|
||||
end_time = Column(DateTime)
|
||||
parameters = Column(String)
|
||||
statistics = Column(String)
|
||||
|
||||
class PriceHistory(Base):
|
||||
__tablename__ = 'price_history'
|
||||
id = Column(Integer, primary_key=True)
|
||||
location = Column(String)
|
||||
zip_code = Column(Integer)
|
||||
city_name = Column(String)
|
||||
price_at_time = Column(DateTime)
|
||||
price = Column(Float)
|
||||
scraper_job_id = Column(Integer, ForeignKey('scraper_job.id'))
|
||||
product_id = Column(Integer, ForeignKey('product.id'))
|
||||
product = relationship("Product", back_populates="price_histories")
|
||||
scraper_job = relationship("ScraperJob")
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = 'user'
|
||||
id = Column(Integer, primary_key=True)
|
||||
username = Column(String)
|
||||
credentials = Column(String)
|
||||
creation_date = Column(DateTime)
|
||||
modification_date = Column(DateTime)
|
||||
|
||||
class RetailerProduct(Base):
|
||||
__tablename__ = 'retailer_product'
|
||||
retailer_id = Column(Integer, ForeignKey('retailer.id'), primary_key=True)
|
||||
product_id = Column(Integer, ForeignKey('product.id'), primary_key=True)
|
||||
|
||||
|
||||
# In[ ]:
|
||||
|
||||
|
||||
# Create the database engine
|
||||
engine = create_engine('sqlite:///user_database.db')
|
||||
Base.metadata.create_all(engine)
|
||||
|
||||
|
||||
# In[ ]:
|
||||
|
||||
|
||||
# Create a session factory
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
|
||||
|
||||
# In[ ]:
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
# Create a command-line tool that parses sys.argv to allow a user to create/edit/delete user objects.
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
app = Flask(__name__)
|
||||
|
||||
# Create a database connection
|
||||
engine = create_engine('sqlite:///user_database.db')
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
|
||||
@app.route('/')
|
||||
def home():
|
||||
# Get all user objects
|
||||
users = session.query(User).all()
|
||||
return render_template('index.html', users=users)
|
||||
|
||||
app.run()
|
||||
|
||||
|
||||
command = sys.argv[1]
|
||||
|
||||
if command == "create":
|
||||
if len(sys.argv) < 4:
|
||||
print("Usage: python script.py create [username] [credentials]")
|
||||
sys.exit(1)
|
||||
|
||||
username = sys.argv[2]
|
||||
credentials = sys.argv[3]
|
||||
|
||||
# Create a new user object
|
||||
new_user = User(username=username, credentials=credentials)
|
||||
session.add(new_user)
|
||||
session.commit()
|
||||
print("User created successfully!")
|
||||
|
||||
elif command == "edit":
|
||||
if len(sys.argv) < 4:
|
||||
print("Usage: python script.py edit [username] [new_credentials]")
|
||||
sys.exit(1)
|
||||
|
||||
username = sys.argv[2]
|
||||
new_credentials = sys.argv[3]
|
||||
|
||||
# Find the user object
|
||||
user = session.query(User).filter_by(username=username).first()
|
||||
|
||||
if user:
|
||||
# Update user credentials
|
||||
user.credentials = new_credentials
|
||||
session.commit()
|
||||
print("User edited successfully!")
|
||||
else:
|
||||
print("User not found!")
|
||||
|
||||
elif command == "delete":
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: python script.py delete [username]")
|
||||
sys.exit(1)
|
||||
|
||||
username = sys.argv[2]
|
||||
|
||||
# Find the user object
|
||||
user = session.query(User).filter_by(username=username).first()
|
||||
|
||||
if user:
|
||||
# Delete the user object
|
||||
session.delete(user)
|
||||
session.commit()
|
||||
print("User deleted successfully!")
|
||||
else:
|
||||
print("User not found!")
|
||||
|
||||
else:
|
||||
print("Usage: python script.py [create|edit|delete] [username] [credentials]")
|
||||
@@ -1,100 +0,0 @@
|
||||
# A quick brain teaser
|
||||
print('What has a head and a tail but no body?')
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
# A coin
|
||||
@@ -1,46 +0,0 @@
|
||||
class BoundedInt():
|
||||
def __init__(self, i, min, max):
|
||||
"""
|
||||
Create a bounded integer.
|
||||
|
||||
Args:
|
||||
i (int): The initial value of the integer.
|
||||
min (int): The minimum value of the integer.
|
||||
max (int): The maximum value of the integer.
|
||||
"""
|
||||
self.i = i
|
||||
self.min = min
|
||||
self.max = max
|
||||
|
||||
def __int__(self):
|
||||
"""
|
||||
Convert the bounded integer to int.
|
||||
|
||||
Returns:
|
||||
int: The value of the bounded integer.
|
||||
"""
|
||||
return self.i
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, BoundedInt):
|
||||
if self.i + other.i > self.max:
|
||||
raise ValueError("Addition exceeds maximum value")
|
||||
return BoundedInt(self.i + other.i, self.min, self.max)
|
||||
elif isinstance(other, int):
|
||||
if self.i + other > self.max:
|
||||
raise ValueError("Addition exceeds maximum value")
|
||||
return BoundedInt(self.i + other, self.min, self.max)
|
||||
else:
|
||||
raise TypeError("Unsupported operand type")
|
||||
|
||||
def __sub__(self, other):
|
||||
if isinstance(other, BoundedInt):
|
||||
if self.i - other.i < self.min:
|
||||
raise ValueError("Subtraction exceeds minimum value")
|
||||
return BoundedInt(self.i - other.i, self.min, self.max)
|
||||
elif isinstance(other, int):
|
||||
if self.i - other < self.min:
|
||||
raise ValueError("Subtraction exceeds minimum value")
|
||||
return BoundedInt(self.i - other, self.min, self.max)
|
||||
else:
|
||||
raise TypeError("Unsupported operand type")
|
||||
@@ -1,67 +0,0 @@
|
||||
from BoundedInt import BoundedInt
|
||||
|
||||
class BoundedIntTester:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def test1(self):
|
||||
bi1 = BoundedInt(0xdeadbeef, min = (0xdeadbeef-1), max = (0xdeadbeef+1))
|
||||
if int(bi1) == 0xdeadbeef:
|
||||
print(f"✅ Test 1 passed!")
|
||||
else:
|
||||
print(f"❌ Test 1 failed, int(bi1) = {int(bi1)}, expected 0xdeadbeef")
|
||||
|
||||
def test2(self):
|
||||
"""
|
||||
Test that addition works for two BoundedInts, and throws an error if the bounds are exceeded.
|
||||
"""
|
||||
bi2 = BoundedInt(1, min = 0, max = 1)
|
||||
bi3 = BoundedInt(1, min = 0, max = 1)
|
||||
try:
|
||||
bi4 = bi2 + bi3 # 1 + 1 = 2, which is more than max = 1
|
||||
print(f"❌ Test 2 failed!")
|
||||
except ValueError as err:
|
||||
print(f"✅ Test 2 passed!")
|
||||
|
||||
def test3(self):
|
||||
"""
|
||||
Test that addition works for two BoundedInts, and throws an error if the bounds are exceeded.
|
||||
"""
|
||||
bi4 = BoundedInt(1, min = 0, max = 1)
|
||||
bi5 = BoundedInt(2, min = 0, max = -1)
|
||||
try:
|
||||
bi6 = bi4 - bi5 # 1 - 2 = (-1), which is less than min = 0
|
||||
print(f"❌ Test 3 failed!")
|
||||
except ValueError as err:
|
||||
print(f"✅ Test 3 passed!")
|
||||
|
||||
def test4(self):
|
||||
"""
|
||||
Test that addition works for a BoundedInt and a regular int, and throws an error if the bounds are exceeded.
|
||||
"""
|
||||
bi7 = BoundedInt(1, min = 0, max = 1)
|
||||
bi8 = 2
|
||||
try:
|
||||
bi9 = bi7 + bi8
|
||||
print(f"❌ Test 4 failed!")
|
||||
except ValueError as err:
|
||||
print(f"✅ Test 4 passed!")
|
||||
|
||||
def test5(self):
|
||||
"""
|
||||
Test that subtraction works for a BoundedInt and a regular int, and throws an error if the bounds are exceeded.
|
||||
"""
|
||||
bi10 = BoundedInt(1, min = 0, max = 1)
|
||||
bi11 = 2
|
||||
try:
|
||||
bi12 = bi10 - 11
|
||||
print(f"❌ Test 5 failed!")
|
||||
except ValueError as err:
|
||||
print(f"✅ Test 5 passed!")
|
||||
|
||||
tester = BoundedIntTester()
|
||||
tester.test1()
|
||||
tester.test2()
|
||||
tester.test3()
|
||||
tester.test4()
|
||||
tester.test5()
|
||||
@@ -1,2 +0,0 @@
|
||||
import sys
|
||||
print(sys.float_info)
|
||||
@@ -1,37 +0,0 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf2580
|
||||
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;\f1\fnil\fcharset0 Menlo-Regular;}
|
||||
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red0\green0\blue0;}
|
||||
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0\c87059;\cssrgb\c0\c0\c0\c3922;}
|
||||
\margl1440\margr1440\vieww11520\viewh8400\viewkind0
|
||||
\deftab720
|
||||
\pard\pardeftab720\partightenfactor0
|
||||
|
||||
\f0\fs32 \cf2 \expnd0\expndtw0\kerning0
|
||||
1. What is the name of the international standard for floating-point representation?\
|
||||
\
|
||||
The IEEE-754 standard describes floating-point formats, a way to represent real numbers in hardware.\
|
||||
\
|
||||
\
|
||||
2. How many bits are the floating point numbers defined by that standard allowed to be?\
|
||||
\
|
||||
The floating-point numbers defined by the international standard can be allowed to be of different lengths depending on the specific interchange format. For binary interchange, the formats can be 16 bits, 32 bits, 64 bits, and any multiple of 32 bits \uc0\u8805 128. For decimal interchange, the formats can be any multiple of 32 bits.\
|
||||
\
|
||||
\
|
||||
3. Does your computer support all those formats? Can you think of an easy way to check with only one line of Python?\
|
||||
\
|
||||
import sys\
|
||||
print(sys.float_info)\
|
||||
\
|
||||
scott@MacBook-Pro-6 python-bootcamp % python3 Floating_Point_Formats.py \
|
||||
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)\
|
||||
\
|
||||
\
|
||||
\pard\pardeftab720\sa320\partightenfactor0
|
||||
\cf2 4. Why doesn't this code give the same answers to the two multiplications?\
|
||||
Because they are different operations. The normal Python multiplication operator will multiply two numbers together and return the product. The Pandas multiplication operator, on the other hand, performs element-wise multiplication on the corresponding columns in a DataFrame. In other words, it multiplies the first element in the first column with the first element in the second column, the second element in the first column with the second element in the second column, and so on. \
|
||||
Floating-point arithmetic has a limited precision due to the finite number of bits used to represent floating-point numbers in binary format. This can lead to rounding errors and loss of precision in arithmetic operations, particularly with very large or very small numbers.\
|
||||
\
|
||||
5. You can use
|
||||
\f1\fs27\fsmilli13600 \cf2 \cb3 sys.getsizeof
|
||||
\f0\fs32 \cf2 \cb1 to see how large a Python object is. Does the size of a Python floating-point number change as it gets larger? Why or why not?\
|
||||
The size of a Python floating-point number does not change as it gets larger. This is because Python uses a fixed number of bytes to represent floating-point numbers, regardless of their value.}
|
||||
@@ -1,54 +0,0 @@
|
||||
# Name three practical differences between Python strings and bytes.
|
||||
# Using sys.getsizeof, see how the sizes may be different.
|
||||
# Do emoji change this answer?
|
||||
|
||||
# Encoding
|
||||
# Strings are created using Unicode character points.
|
||||
# While bytes are used to represent actual bytes in memory, which can be encoded using ASCII or UTF-8.
|
||||
|
||||
# Usage
|
||||
# Strings are usually used to represent text.
|
||||
# While bytes are used to represent binary data.
|
||||
|
||||
# Memory Size
|
||||
# Strings take up more memory than bytes, because they are Unicode-based and can contain any character.
|
||||
# While bytes are limited to binary data.
|
||||
|
||||
|
||||
print("---------------------------------------------")
|
||||
print("This is the Memory Size test print out:")
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
my_string = "Hello, world!"
|
||||
my_bytes = b'\x48\x65\x6c\x6c'
|
||||
|
||||
print(sys.getsizeof(my_string)) # Prints 62
|
||||
print(sys.getsizeof(my_bytes)) # Prints 37
|
||||
|
||||
print()
|
||||
print('Test the emoji:')
|
||||
|
||||
x = 'pizza' # Prints 54
|
||||
y = b'pizza' # Prints 38
|
||||
z = '🍕' #Prints 80
|
||||
|
||||
print(sys.getsizeof(x))
|
||||
print(sys.getsizeof(y))
|
||||
print(sys.getsizeof(z))
|
||||
|
||||
|
||||
print("---------------------------------------------")
|
||||
|
||||
print("This is the String to Sequence of Numbers print out:")
|
||||
|
||||
def String_to_SequenceofNumbers():
|
||||
my_string = input("Enter a string: ")
|
||||
num_sequence = [ord(c) for c in my_string]
|
||||
print(num_sequence)
|
||||
|
||||
if __name__ == "__main__":
|
||||
String_to_SequenceofNumbers()
|
||||
|
||||
print("---------------------------------------------")
|
||||
@@ -1,63 +0,0 @@
|
||||
# 1. Why does ord("😀") give a different number than 0xf09f9880, which is what the hexdump of the same character yields?
|
||||
#
|
||||
# The ord() function returns the Unicode code point of a character as an integer, which is 128512 for the smiley face.
|
||||
# However, the hexdump command, returns the UTF-8 encoding of character.
|
||||
# The hexadecimal representation of 128512 is 0x1F600.
|
||||
# The UTF-8 encoding of the "😀" character is represented by the sequence of bytes F0 9F 98 80 in hexadecimal.
|
||||
# UTF-8 is one of the encoding schemes used to represent Unicode characters as binary data.
|
||||
#
|
||||
#
|
||||
# 8. Hypothetical Situation: If the dataframe is not formatted or cleaned, while the column storing the tomoto sales data isn't named exactly same as 'Tomato_Sales'
|
||||
# It will raise a KeyError instead.
|
||||
#
|
||||
#
|
||||
# 9. The solution of the hypothetical situation from my question 8:
|
||||
|
||||
def read_tomato_sales(file_name):
|
||||
data = pd.read_csv(file_name)
|
||||
if not pd.api.types.is_numeric_dtype(data["Tomato_Sales"]):
|
||||
raise TypeError("Tomato_Sales column should contain only numeric values")
|
||||
total_sales = data.iloc[:, -1].sum() # This is the key
|
||||
print(f"Total tomato sales: {total_sales}")
|
||||
# read_tomato_sales("tomato_sales_error.csv")
|
||||
|
||||
|
||||
# 10. Different human languages can use various character encodings such as UTF-8, UTF-16, or ASCII.
|
||||
# While using bytes, you can work with raw data without worrying about specific encodings.
|
||||
# This allows us to avoid encoding-related errors and ensures compatibility across different language texts.
|
||||
|
||||
def encode_decode_data():
|
||||
print('-' * 20)
|
||||
data = input("Enter a sentence using any language: ")
|
||||
print('-' * 20)
|
||||
print("The sentence you entered is: {}".format(data))
|
||||
print('-' * 20)
|
||||
encoded_data = data.encode('utf-8')
|
||||
print("This sentence after encoded is: {}".format(encoded_data))
|
||||
print('-' * 20)
|
||||
byte_length = len(encoded_data)
|
||||
print("The byte length of this sentence is: {}".format(byte_length))
|
||||
print('-' * 20)
|
||||
decoded_data = encoded_data.decode()
|
||||
print("This sentence after decoded is: {}".format(decoded_data))
|
||||
print('-' * 20)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_function = 'function1'
|
||||
|
||||
if run_function == 'function1':
|
||||
encode_decode_data()
|
||||
elif run_function == 'function2':
|
||||
read_tomato_sales(file_name)
|
||||
|
||||
|
||||
# 2.5. REPL stands for Read-Eval-Print Loop.
|
||||
# A REPL is an interactive programming environment that allows you to read input, evaluate expressions or statements, print output, and repeat the process.
|
||||
# It provides a quick way to experiment with code, test small snippets, and get immediate feedback.
|
||||
# The Python REPL allows you to interactively enter Python code and see the results immediately without needing to write a full script and execute it separately.
|
||||
|
||||
|
||||
# 3. The '_' is a convention that holds the value of the last printed expression or the result of the last evaluated expression.
|
||||
# The actual type of the "_" variable depends on the value assigned to it.
|
||||
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
# 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()
|
||||
@@ -1,91 +0,0 @@
|
||||
# 5. What does this do? print("\007") Can you figure out why?
|
||||
|
||||
# It is a ASCII Bell character.
|
||||
# It generates a beep sound or a system alert depending on the platform and environment where the code is executed.
|
||||
# It is often used to trigger attention or alert the user in certain situations or as a way to generate a simple sound signal in text-based interfaces.
|
||||
|
||||
# BUT NOTHING HAPPENED ON MAC.
|
||||
|
||||
|
||||
|
||||
# 6. What does this do? print("abcdefg\rhijklmnop") Can you figure out why?
|
||||
|
||||
# '\r' is a carriage return character
|
||||
# When the string is printed, the carriage return character '\r' causes the cursor to return to the beginning of the line.
|
||||
# So when "hijklmnop" is printed, the cursor moves back to the start of the line, and the subsequent text "abcdefg" overwrites the initial characters.
|
||||
|
||||
# The output is gonna be 'hijklmnop'.
|
||||
|
||||
|
||||
|
||||
# 7. To shut down the HTTP server afterward, using Ctrl + C to interrupt the execution of the Python program.
|
||||
|
||||
import http.server
|
||||
import socketserver
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
|
||||
class MyRequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/plain')
|
||||
self.end_headers()
|
||||
output_string = "abcdefg\rhijklmnop"
|
||||
self.wfile.write(output_string.encode())
|
||||
|
||||
PORT = 8000
|
||||
Handler = MyRequestHandler
|
||||
httpd = socketserver.TCPServer(("", PORT), Handler)
|
||||
print(f"Serving on port {PORT}")
|
||||
|
||||
httpd.serve_forever()
|
||||
|
||||
# The HTTP server sends the response over the network to the client, which is typically a web browser.
|
||||
# In this function, the server sends an HTTP response with a status code of 200 and a content type of "text/plain".
|
||||
# The response body is set to the string "abcdefg\rhijklmnop" encoded as bytes.
|
||||
# When the client receives this response, it interprets the \r character as a normal character and displays the entire string "abcdefg\rhijklmnop" as it is.
|
||||
|
||||
# The '\r' character is a carriage return character, which is a control character used to return the cursor to the beginning of the current line.
|
||||
# The behavior of the carriage return character '\r' can depend on the platform and how the output is handled.
|
||||
|
||||
# For example:
|
||||
# In Safari and Chrome, the "http://localhost:8000" shows:
|
||||
# abcdefg
|
||||
# hijklmnop
|
||||
# In Macbook Terminal, the "curl http://localhost:8000" shows:
|
||||
# hijklmnop%
|
||||
|
||||
|
||||
|
||||
# 8. Think of a way someone might try to commit a crime or hide an embezzlement scheme using the answers to the above two questions.
|
||||
|
||||
# The key is by manipulating or altering the output displayed on a web page versus what is actually happening in the system.
|
||||
|
||||
# Case 1:
|
||||
# Show the false financial transactions to earn the cut.
|
||||
# Case 2:
|
||||
# Delivey the heist planning details and hide any suspicious activity.
|
||||
# Case 3:
|
||||
# Overwrite the previously displayed information for the false testimony purpose.
|
||||
|
||||
|
||||
|
||||
# 9. Think of how you would do input validation to prevent such a crime. Replace the code REPLACE ME here so the tests pass:
|
||||
|
||||
def validate(input_str):
|
||||
if '\r' in input_str or '\n' in input_str:
|
||||
raise ValueError("Crime detected!")
|
||||
|
||||
try:
|
||||
validate("abcdefg")
|
||||
print("✅ test1 pass!")
|
||||
except ValueError:
|
||||
print("❌ test1 fail!")
|
||||
|
||||
try:
|
||||
validate("abcdefg\rhijklmnop")
|
||||
print("❌ test2 fail!")
|
||||
except ValueError:
|
||||
print("✅ test2 pass!")
|
||||
|
||||
# Test 1 pass means there is no ValueError
|
||||
# Test 2 pass means the ValueError has been detected
|
||||
@@ -1,76 +0,0 @@
|
||||
########## This file only contains the question 2, 4, and 10. The rest is in the BoundedInt.py. ##########
|
||||
|
||||
|
||||
|
||||
# 2. Modify the template to pass test 1, which checks that int() called on your class will return the value of i.
|
||||
|
||||
# class BoundedInt():
|
||||
# def __init__(self, i, min, max):
|
||||
# """
|
||||
# Create a bounded integer.
|
||||
|
||||
# Args:
|
||||
# i (int): The initial value of the integer.
|
||||
# min (int): The minimum value of the integer.
|
||||
# max (int): The maximum value of the integer.
|
||||
# """
|
||||
# self.i = i
|
||||
# self.min = min
|
||||
# self.max = max
|
||||
|
||||
# def __int__(self):
|
||||
# """
|
||||
# Convert the bounded integer to int.
|
||||
|
||||
# Returns:
|
||||
# int: The value of the bounded integer.
|
||||
# """
|
||||
# return self.i
|
||||
|
||||
|
||||
|
||||
# 4. In that reading material, there's a sentence that starts with "For instance, to evaluate the expression x + y, "...
|
||||
# What do you think the types of x and y are? Guess, without checking first.
|
||||
# What are they, actually? You can use the debugger's local window to find out.
|
||||
|
||||
# x might be an instance of a class that has defined the __add__() method
|
||||
# And y is the object that is compatible with the x instance for the addition operation.
|
||||
|
||||
class MyClass:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, MyClass):
|
||||
return MyClass(self.value + other.value)
|
||||
elif isinstance(other, int):
|
||||
return MyClass(self.value + other)
|
||||
else:
|
||||
raise TypeError("Unsupported operand type.")
|
||||
|
||||
# Example usage
|
||||
obj1 = MyClass(5)
|
||||
obj2 = MyClass(10)
|
||||
result1 = obj1 + obj2 # Calls obj1.__add__(obj2)
|
||||
print(result1.value) # Output: 15
|
||||
|
||||
result2 = obj1 + 3 # Calls obj1.__add__(3)
|
||||
print(result2.value) # Output: 8
|
||||
|
||||
|
||||
|
||||
# 10. Think about how you would change the template so it could allow adding a BoundedInt to an emoji,
|
||||
# if there was a hypothetical function sentiment(emoji) which returned a floating point number from -10.0 to 10.0
|
||||
# which indicated whether the emoji was happy or sad. e.g. BoundedInt(1, min = 1, max = 10) + 😁 would raise ValueError.
|
||||
|
||||
# By adding the conceptional function 'sentiment(emoji)' in the '__add__()' method
|
||||
# The sentiment will analyze the happy level of the input emoji and return a floating number from a number range
|
||||
# For example:
|
||||
# 10 for a 😊 smiley face
|
||||
# -10 for a frowny face
|
||||
# 0 for a 🍕
|
||||
# The protential code can be like this:
|
||||
'''
|
||||
elif isinstance(other, str) and sentiment(other) < 0:
|
||||
aise ValueError("Cannot add a BoundedInt to a sad emoji")
|
||||
'''
|
||||
@@ -1,77 +0,0 @@
|
||||
########## Some commands in pdb ##########
|
||||
# help: Display a list of available pdb commands or get help on a specific command.
|
||||
# break or b: Set a breakpoint at a specific line or function.
|
||||
# continue or c: Continue execution until the next breakpoint or the program finishes.
|
||||
# step or s: Step into the next line of code, diving into function calls.
|
||||
# next or n: Step over the next line of code, without diving into function calls.
|
||||
# return or r: Continue execution until the current function returns.
|
||||
# list or l: Show the current line of code and surrounding lines.
|
||||
# print or p: Evaluate and print the value of an expression or variable.
|
||||
# watch: Set a watchpoint on an expression or variable. The debugger will break when the value changes.
|
||||
# quit or q: Quit the debugger and stop execution.
|
||||
|
||||
|
||||
########## There is a main() function at the end ##########
|
||||
|
||||
|
||||
# 2. Provide an example script where setting a breakpoint on a particular line
|
||||
# Then using either step over or step into will yield the same result.
|
||||
|
||||
class Same_StepOverStepInto_Result:
|
||||
def calculation2(self, a, b):
|
||||
result = a + b
|
||||
product = self.multiply(a, b) # Step into this method call
|
||||
|
||||
breakpoint() # Set a breakpoint here
|
||||
|
||||
print(f"The sum is: {result}")
|
||||
print(f"The product is: {product}")
|
||||
|
||||
def multiply(self, x, y):
|
||||
return x * y
|
||||
|
||||
|
||||
# calculator2 = Same_StepOverStepInto_Result()
|
||||
# calculator2.calculation2(6, 7)
|
||||
|
||||
|
||||
|
||||
# 3. Here is another example which will provide different results from 'step' and 'next' commands
|
||||
|
||||
class Diff_StepOverStepInto_Result:
|
||||
def multiply(self, a, b):
|
||||
return a * b
|
||||
|
||||
def calculation3(self, a, b):
|
||||
result = a + b
|
||||
|
||||
breakpoint() # Set a breakpoint here
|
||||
|
||||
product = self.multiply(a, b)
|
||||
|
||||
print(f"The sum is: {result}")
|
||||
print(f"The product is: {product}")
|
||||
|
||||
|
||||
# calculator3 = Diff_StepOverStepInto_Result()
|
||||
# calculator3.calculation3(6, 7)
|
||||
|
||||
|
||||
|
||||
# Choose wich Class to run
|
||||
def main():
|
||||
choice = input("Enter 2 to run Q2 class for same result, 3 to run Q3 class for different result: ")
|
||||
|
||||
if choice == '2':
|
||||
print('Here is the sample task for Question 2:')
|
||||
calculator2 = Same_StepOverStepInto_Result()
|
||||
calculator2.calculation2(6, 7)
|
||||
elif choice == '3':
|
||||
print('Here is the sample task for Question 3:')
|
||||
calculator3 = Diff_StepOverStepInto_Result()
|
||||
calculator3.calculation3(6, 7)
|
||||
else:
|
||||
print("Please only choose between 2 and 3")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,79 +0,0 @@
|
||||
class Vector_1:
|
||||
def __init__(self, x, y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, Vector_1):
|
||||
# Add the corresponding coordinates of both vectors
|
||||
new_x = self.x + other.x
|
||||
new_y = self.y + other.y
|
||||
return Vector_1(new_x, new_y)
|
||||
else:
|
||||
raise TypeError("Unsupported operand type: +")
|
||||
|
||||
def __str__(self):
|
||||
return f"Vector({self.x}, {self.y})"
|
||||
|
||||
# # Create two Vector instances
|
||||
# vector1 = Vector_1(2, 3)
|
||||
# vector2 = Vector_1(4, 5)
|
||||
|
||||
# # Add two Vector instances using the + operator
|
||||
# result1 = vector1 + vector2
|
||||
|
||||
# # Print the result
|
||||
# print(result1)
|
||||
|
||||
|
||||
|
||||
class Vector_2:
|
||||
def __init__(self, x, y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, Vector_2):
|
||||
# Add the corresponding coordinates of both vectors
|
||||
new_x = self.x + other.x
|
||||
new_y = self.y + other.y
|
||||
return Vector_2(new_x, new_y)
|
||||
else:
|
||||
raise TypeError("Unsupported operand type: +")
|
||||
|
||||
# def __str__(self):
|
||||
# return f"Vector({self.x}, {self.y})"
|
||||
|
||||
# # Create two Vector instances
|
||||
# vector3 = Vector_2(2, 3)
|
||||
# vector4 = Vector_2(4, 5)
|
||||
|
||||
# # Add two Vector instances using the + operator
|
||||
# result2 = vector3 + vector4
|
||||
|
||||
# # Print the result
|
||||
# print(result2)
|
||||
|
||||
|
||||
def main():
|
||||
# Create two Vector instances
|
||||
vector1 = Vector_1(2, 3)
|
||||
vector2 = Vector_1(4, 5)
|
||||
# Add two Vector instances using the + operator
|
||||
result1 = vector1 + vector2
|
||||
# Print the result
|
||||
print("This is printout of the Class using __str__() method:")
|
||||
print(result1)
|
||||
|
||||
# Create two Vector instances
|
||||
vector3 = Vector_2(2, 3)
|
||||
vector4 = Vector_2(4, 5)
|
||||
# Add two Vector instances using the + operator
|
||||
result2 = vector3 + vector4
|
||||
# Print the result
|
||||
print("This is printout of the Class without using __str__() method:")
|
||||
print(result2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,56 +0,0 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf2580
|
||||
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
{\*\expandedcolortbl;;}
|
||||
\margl1440\margr1440\vieww11520\viewh8400\viewkind0
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
||||
|
||||
\f0\fs24 \cf0 scott@MacBook-Pro-6 Scott_Submissions % python3 HW7.py\
|
||||
Enter 2 to run Q2 class for same result, 3 to run Q3 class for different result: 1\
|
||||
Please only choose between 2 and 3\
|
||||
scott@MacBook-Pro-6 Scott_Submissions % python3 HW7.py\
|
||||
Enter 2 to run Q2 class for same result, 3 to run Q3 class for different result: 2\
|
||||
Here is the sample task for Question 2:\
|
||||
> /Users/scott/Desktop/GTSP/python-bootcamp/Scott_Submissions/HW7.py(27)calculation2()\
|
||||
-> print(f"The sum is: \{result\}")\
|
||||
(Pdb) step\
|
||||
The sum is: 13\
|
||||
> /Users/scott/Desktop/GTSP/python-bootcamp/Scott_Submissions/HW7.py(28)calculation2()\
|
||||
-> print(f"The product is: \{product\}")\
|
||||
(Pdb) c\
|
||||
The product is: 42\
|
||||
scott@MacBook-Pro-6 Scott_Submissions % python3 HW7.py\
|
||||
Enter 2 to run Q2 class for same result, 3 to run Q3 class for different result: 2\
|
||||
Here is the sample task for Question 2:\
|
||||
> /Users/scott/Desktop/GTSP/python-bootcamp/Scott_Submissions/HW7.py(27)calculation2()\
|
||||
-> print(f"The sum is: \{result\}")\
|
||||
(Pdb) next\
|
||||
The sum is: 13\
|
||||
> /Users/scott/Desktop/GTSP/python-bootcamp/Scott_Submissions/HW7.py(28)calculation2()\
|
||||
-> print(f"The product is: \{product\}")\
|
||||
(Pdb) c\
|
||||
The product is: 42\
|
||||
scott@MacBook-Pro-6 Scott_Submissions % python3 HW7.py\
|
||||
Enter 2 to run Q2 class for same result, 3 to run Q3 class for different result: 3\
|
||||
Here is the sample task for Question 3:\
|
||||
> /Users/scott/Desktop/GTSP/python-bootcamp/Scott_Submissions/HW7.py(50)calculation3()\
|
||||
-> product = self.multiply(a, b)\
|
||||
(Pdb) step\
|
||||
--Call--\
|
||||
> /Users/scott/Desktop/GTSP/python-bootcamp/Scott_Submissions/HW7.py(42)multiply()\
|
||||
-> def multiply(self, a, b):\
|
||||
(Pdb) c\
|
||||
The sum is: 13\
|
||||
The product is: 42\
|
||||
scott@MacBook-Pro-6 Scott_Submissions % python3 HW7.py\
|
||||
Enter 2 to run Q2 class for same result, 3 to run Q3 class for different result: 3\
|
||||
Here is the sample task for Question 3:\
|
||||
> /Users/scott/Desktop/GTSP/python-bootcamp/Scott_Submissions/HW7.py(50)calculation3()\
|
||||
-> product = self.multiply(a, b)\
|
||||
(Pdb) next\
|
||||
> /Users/scott/Desktop/GTSP/python-bootcamp/Scott_Submissions/HW7.py(52)calculation3()\
|
||||
-> print(f"The sum is: \{result\}")\
|
||||
(Pdb) c\
|
||||
The sum is: 13\
|
||||
The product is: 42\
|
||||
scott@MacBook-Pro-6 Scott_Submissions % }
|
||||
@@ -1,18 +0,0 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
# Generate two random 64-bit integers
|
||||
num1 = np.random.randint(0, 10 - 1)
|
||||
num2 = np.random.randint(0, 10 - 1)
|
||||
|
||||
# Multiply them together using the normal Python multiplication operator
|
||||
print(f"num1 * num2 = {num1 * num2}")
|
||||
|
||||
# Create a Pandas DataFrame with the generated numbers
|
||||
data = {'Number1': [num1], 'Number2': [num2]}
|
||||
df = pd.DataFrame(data)
|
||||
|
||||
# Multiply the numbers together using the Pandas multiplication operator
|
||||
df['Product'] = df['Number1'] * df['Number2']
|
||||
|
||||
print(df)
|
||||
@@ -1,4 +0,0 @@
|
||||
import sys
|
||||
num = 99999999999
|
||||
size = sys.getsizeof(num)
|
||||
print(f"The size of the float is {size} bytes.")
|
||||
@@ -1,117 +0,0 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf2580
|
||||
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
|
||||
{\colortbl;\red255\green255\blue255;\red26\green26\blue26;\red255\green255\blue255;\red39\green40\blue50;
|
||||
}
|
||||
{\*\expandedcolortbl;;\cssrgb\c13333\c13333\c13333;\cssrgb\c100000\c100000\c100000;\cssrgb\c20392\c20784\c25490;
|
||||
}
|
||||
\margl1440\margr1440\vieww28300\viewh17700\viewkind0
|
||||
\deftab720
|
||||
\pard\pardeftab720\parhyphenfactor20\partightenfactor0
|
||||
|
||||
\f0\fs32 \cf2 \cb3 \expnd0\expndtw0\kerning0
|
||||
CPython implementation detail: CPython currently uses a reference-counting scheme with (optional) delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references.\
|
||||
\
|
||||
What is a reference-counting scheme?\
|
||||
It refers to a memory management technique where each object in a programming language implementation, such as CPython, keeps track of the number of references pointing to it. \
|
||||
Whenever a reference is created to an object, its reference count is increased, and when a reference is deleted or goes out of scope, the reference count is decreased. \
|
||||
\
|
||||
What is a reference?\
|
||||
In the context of memory management, a "reference" refers to an identifier or value that allows access to an object in a programming language. \
|
||||
It is a way to refer to or point to the memory location where an object is stored.\
|
||||
\
|
||||
What is the advantage of reference-counting scheme?\
|
||||
The advantage of the reference-counting scheme is that it allows objects to be deallocated immediately when they are no longer needed. \
|
||||
It ensures efficient memory management because objects can be freed as soon as their reference count reaches zero, without the need for more complex garbage collection algorithms.\
|
||||
\
|
||||
What is a garbage?\
|
||||
In the context of memory management, "garbage" refers to objects that are no longer reachable or used by the program but still occupy memory. \
|
||||
This typically occurs when objects are created dynamically during program execution but are not properly deallocated or no longer accessible. \
|
||||
Garbage collection is the process of identifying and reclaiming memory occupied by such unused objects, making it available for reuse. \
|
||||
The reference-counting scheme used by CPython helps in automatically deallocating most objects as soon as they become unreachable. \
|
||||
However, in the case of circular references, where objects refer to each other in a loop, additional mechanisms are required to detect and collect such cyclically linked garbage. It\'92s called "delayed detection of cyclically linked garbage" to collect and deallocate objects that are involved in cyclic references.\
|
||||
\
|
||||
\
|
||||
\
|
||||
What is a __blabla__(): method?\
|
||||
In Python, the following are special attributes (also known as dunder attributes) that can be accessed on objects or functions.\
|
||||
These special attributes provide additional information or access to specific properties of objects in Python. \
|
||||
\
|
||||
What is the advantages of the dunder method?\
|
||||
Overall, dunder attributes provide flexibility, customization, and enhanced functionality to Python objects and classes. \
|
||||
They contribute to the expressive nature of the language and enable powerful features like operator overloading and introspection.\
|
||||
\
|
||||
Convention: Dunder attributes follow a specific naming convention, starting and ending with double underscores (__). This convention makes them easily recognizable and distinguishes them from regular attributes.\
|
||||
Customization: Dunder attributes allow you to customize and define the behavior of objects and classes. By implementing specific dunder methods, you can change how objects behave in certain situations, such as arithmetic operations, string representation, comparisons, and more.\
|
||||
Operator Overloading: Dunder attributes enable operator overloading, allowing objects to participate in built-in operations like addition (+), subtraction (-), equality (==), and more. This makes it possible to define meaningful operations for custom classes.\
|
||||
Introspection: Dunder attributes provide a way to introspect and access information about objects and classes. For example, name and doc allow you to retrieve the name and documentation of an object. This introspection capability is useful for debugging, documentation generation, and code analysis.\
|
||||
Integration with Language Features: Dunder attributes seamlessly integrate with various language features, such as iteration (with iter), context managers (with enter and exit), attribute access (with getattr, setattr), and more. This allows you to leverage the full power of the Python language in your classes.\
|
||||
Code Readability: By following the conventions for dunder attributes, your code becomes more readable and understandable by other Python developers. They can easily recognize and understand the purpose of these special attributes.\
|
||||
\
|
||||
\
|
||||
\
|
||||
What is a Von Neumann\'92s model of a \'93stored program computer\'94?\
|
||||
Von Neumann's model of a "stored program computer" is a fundamental concept in computer architecture that describes the organization and operation of modern digital computers.\
|
||||
It describes a computer architecture where instructions and data are stored together in memory, enabling the execution of instructions as data, and forming the basis of programmable digital computers.\
|
||||
The distinguishing feature of Von Neumann's model is that both data and instructions are stored in the same memory. This means that the instructions that govern the computer's operations can be treated as data and manipulated like any other type of information. This concept, known as the "stored program concept," allows for the flexibility and programmability of modern computers.\
|
||||
\
|
||||
\
|
||||
\
|
||||
\pard\pardeftab720\partightenfactor0
|
||||
\cf4 \cb1 What is the difference between identity and type?\
|
||||
Identity: \
|
||||
The identity of an object is a unique identifier that remains constant throughout the object's lifetime. \
|
||||
It can be thought of as the object's address in memory. \
|
||||
Python provides a built-in function called id() that returns an integer representing the identity of an object. \
|
||||
The identity never changes once the object is created, and no two objects can have the same identity at the same time.\
|
||||
Type: \
|
||||
The type of an object defines the category or class to which the object belongs. \
|
||||
It determines the behavior of the object and the operations that can be performed on it. \
|
||||
In Python, the type of an object is determined by its class, which defines the object's characteristics and behavior. \
|
||||
The type of an object can be obtained using the type() function.\
|
||||
\
|
||||
To summarize, the identity of an object is a unique identifier associated with its memory location, while the type of an object defines its category or class, determining its behavior and the operations that can be performed on it.\
|
||||
\
|
||||
\
|
||||
\
|
||||
The important distinction between immutability and having an unchangeable value in the context of container objects that reference mutable objects in Python.\
|
||||
In Python, immutability refers to the property of an object that prevents its internal state or structure from being modified after it is created. Immutable objects, such as integers, strings, and tuples, cannot be changed once they are created. However, when an immutable container object (like a tuple or a frozenset) contains a reference to a mutable object (such as a list or a set), the value of the mutable object can be modified even though the container object itself cannot be changed.\
|
||||
So, while the value of the mutable object can be altered, the container object is still considered immutable because its internal structure (the collection of objects it contains) cannot be changed. The container object cannot be modified to add, remove, or replace elements, but the mutable object it references can be modified independently.\
|
||||
Therefore, the concept of immutability is more subtle than simply having an unchangeable value. It refers to the inability to modify the structure or internal state of an object, but it doesn't necessarily guarantee that all the objects referenced by an immutable container are themselves immutable.\
|
||||
\
|
||||
\
|
||||
\
|
||||
What is a close() method in Python?\
|
||||
The close() method is typically invoked on an object representing the file or resource. \
|
||||
Calling the close() method can release the associated system resources and ensure that any buffered data is written to the disk.\
|
||||
\
|
||||
It's important to note that closing a file or resource is good practice to free up system resources and prevent any potential issues. Failing to close resources properly can result in resource leaks and may lead to unexpected behavior in your program.\
|
||||
\
|
||||
\
|
||||
\
|
||||
\'93try...finally\'94 statement:\
|
||||
The try...finally statement is used to ensure that certain code is always executed, regardless of whether an exception occurs or not. \
|
||||
The code within the try block is executed, and if an exception occurs, it can be caught and handled using an appropriate except block. After the try block (and any associated except blocks), the code within the finally block is executed, ensuring that it always runs, regardless of exceptions. This is useful for cleaning up resources or releasing locks, even if an exception occurs.\cf2 \cb3 \
|
||||
\pard\pardeftab720\parhyphenfactor20\partightenfactor0
|
||||
\cf2 \
|
||||
\
|
||||
\
|
||||
\'93with\'94 statement:\
|
||||
The with statement provides automatic resource management, improves code readability, handles exceptions effectively, and allows for the creation of custom context managers. It is a recommended approach for managing resources that need proper initialization and cleanup, such as files, database connections, network sockets, and more. By using the with statement, you can ensure that your code is more robust, maintainable, and less prone to resource leaks and error handling issues.\
|
||||
\
|
||||
\
|
||||
\
|
||||
What is a container?\
|
||||
A container refers to an object that can hold multiple other objects or values. \
|
||||
Examples of containers in Python include tuples, lists, dictionaries, sets, and other collection types.\
|
||||
Containers are used to store and organize multiple objects or values together. They provide a way to group related data and operate on them as a whole. \
|
||||
\
|
||||
\
|
||||
\
|
||||
What is a type hierarchy?\
|
||||
The type hierarchy in Python refers to the organization and relationships among different types or classes in the Python programming language. \
|
||||
It defines how types are related to each other and how they inherit attributes and behaviors from their parent types.\
|
||||
the type hierarchy in Python provides a structured organization of types, allowing for code reuse, inheritance, and polymorphism, which are fundamental principles of object-oriented programming.\
|
||||
\
|
||||
\
|
||||
\
|
||||
## The attached file HW7_test.py provides an example on how dunder method works. Don\'92t forget to check it out.}
|
||||
@@ -1,7 +0,0 @@
|
||||
import time
|
||||
|
||||
i=0
|
||||
while True:
|
||||
print(f"\015{i=}", end='')
|
||||
i += 1
|
||||
time.sleep(0.2)
|
||||
@@ -1,28 +0,0 @@
|
||||
import pdb
|
||||
|
||||
def calculate_average(numbers):
|
||||
total = sum(numbers)
|
||||
average = total / len(numbers)
|
||||
return average
|
||||
|
||||
def main():
|
||||
data = [1, 2, 3, 4, 5]
|
||||
|
||||
pdb.set_trace()
|
||||
result = calculate_average(data)
|
||||
print("The average is:", result)
|
||||
|
||||
pdb.set_trace() # Set a breakpoint at this line
|
||||
|
||||
print("Program execution resumed.")
|
||||
# ... continue with the rest of your code
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
# n or next: Execute the next line of code.
|
||||
# s or step: Step into a function call.
|
||||
# c or continue: Continue execution until the next breakpoint or the program's end.
|
||||
# p or print: Print the value of a variable.
|
||||
# q or quit: Quit the debugger and exit the program.
|
||||
@@ -1,5 +0,0 @@
|
||||
char1 = "u"
|
||||
result1 = ord(char1)
|
||||
print("ASCII value of the character {} is {}.".format(char1, result1))
|
||||
|
||||
|
||||
@@ -0,0 +1,277 @@
|
||||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
|
||||
|
||||
from google.cloud import pubsub_v1
|
||||
from google.api_core.exceptions import DeadlineExceeded
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
from selenium.webdriver.common.by import By
|
||||
import json
|
||||
import time
|
||||
from concurrent.futures import TimeoutError
|
||||
import pandas as pd
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
import selenium.common.exceptions
|
||||
import re
|
||||
from datetime import datetime
|
||||
import arrow
|
||||
import subprocess
|
||||
import concurrent.futures
|
||||
|
||||
# This script is used to load the new price and the timestamp and append such data to an existing key in the HDF5 file "product1.h5"
|
||||
|
||||
def get_element_text(driver, class_name_prefix):
|
||||
'''
|
||||
Return the text in the first element with a given class name.
|
||||
|
||||
Note that XPath doesn't have a function to check if a given word is present
|
||||
in a list of words, so using contains() will match a class name even if
|
||||
the class name is a substring of the class name being matched against.
|
||||
To prevent this, we use spaces as a delimiter at the beginning and end of
|
||||
the class name, and ensure there's only one space before and after all
|
||||
class names in the class name list.
|
||||
|
||||
Example: consider two class names with cache-busting suffixes:
|
||||
* Header_soldStatusNotice__12345
|
||||
* Header_soldStatusNoticeBackground__ABCDE
|
||||
|
||||
Matching against Header_soldStatusNotice using a naive implementation with
|
||||
`contains()` would match both class names, even though only the first one
|
||||
is the correct match.
|
||||
'''
|
||||
# Construct xpath selector.
|
||||
xpath_str = "//*[contains(" # Step 1: search for a class name by matching the beginning of the class name against...
|
||||
xpath_str += "concat(' ', " # Step 2: a leading space, followed by...
|
||||
xpath_str += "normalize-space(@class), " # Step 3: the list of class names, separated by single spaces...
|
||||
xpath_str += "' '), " # Step 4: a trailing space...
|
||||
xpath_str += f"' {class_name_prefix} ')]" # Step 5: compared against the class name with a single space on either side.
|
||||
try:
|
||||
match = driver.find_element(By.XPATH, xpath_str)
|
||||
return match.get_attribute('textContent')
|
||||
except selenium.common.exceptions.NoSuchElementException as nsee:
|
||||
pass
|
||||
|
||||
# We didn't find a match, try again by doing a prefix match and assume
|
||||
# the full class name ends with two underscores followed by a cache-
|
||||
# busting string.
|
||||
xpath_str = "//*[contains(" # Step 1: search for a class name by matching the beginning of the class name against...
|
||||
xpath_str += "concat(' ', " # Step 2: a leading space, followed by...
|
||||
xpath_str += "normalize-space(@class)), " # Step 3: the list of class names, separated by single spaces...
|
||||
xpath_str += f"' {class_name_prefix}__')]" # Step 4: compared against the class name prefixed with a single space and ending with two underscores.
|
||||
try:
|
||||
match = driver.find_element(By.XPATH, xpath_str)
|
||||
return match.get_attribute('textContent')
|
||||
except selenium.common.exceptions.NoSuchElementException as nsee:
|
||||
pass
|
||||
|
||||
# No match, return empty string.
|
||||
return ''
|
||||
|
||||
|
||||
def scrape_product_price(project_id, subscription_name, url):
|
||||
# Create an empty dataframe to store the prices
|
||||
df_new = pd.DataFrame(columns=['Product ID', 'Zip Code', 'Shown Price', 'Minimum Quantity', 'Total Price', 'Unit Price','Sales Count','Sold Status'])
|
||||
print(f"Created a dataframe: {df_new}")
|
||||
|
||||
# Configure the Selenium driver options
|
||||
options = Options()
|
||||
options.add_argument('--disable-gpu')
|
||||
driver = webdriver.Chrome(options=options)
|
||||
|
||||
# Set up Pub/Sub subscription
|
||||
subscriber = pubsub_v1.SubscriberClient()
|
||||
subscription_path = subscriber.subscription_path(project_id, subscription_name)
|
||||
|
||||
# Load the product page and extract the __NEXT_DATA__ data
|
||||
product_id = url.split("/")[-1][:5]
|
||||
driver.delete_all_cookies()
|
||||
driver.get(url)
|
||||
|
||||
# Close the cookies setting window
|
||||
try:
|
||||
cookie_button = WebDriverWait(driver, 2).until(
|
||||
EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div[2]/div/div/div[3]/button"))
|
||||
)
|
||||
print(f"cookie_button = {cookie_button}")
|
||||
cookie_button.click()
|
||||
except:
|
||||
pass
|
||||
|
||||
# Clear any modal dialog
|
||||
try:
|
||||
modal_close = WebDriverWait(driver, 2).until(
|
||||
EC.presence_of_element_located((By.XPATH, "//*[contains(concat(' ', normalize-space(@class), ' '), ' icon-icon-close-s ')]"))
|
||||
)
|
||||
print(f"modal_close = {modal_close}")
|
||||
modal_close.click()
|
||||
except:
|
||||
pass
|
||||
|
||||
def callback(message):
|
||||
# Extract zip code from message data
|
||||
zip_code = message.message.data.decode('utf-8')
|
||||
print(f"Received zip code: {zip_code}")
|
||||
|
||||
try:
|
||||
# Clear any modal dialog
|
||||
modal_close = WebDriverWait(driver, 2).until(
|
||||
EC.presence_of_element_located((By.XPATH, "//*[contains(concat(' ', normalize-space(@class), ' '), ' icon-icon-close-s ')]"))
|
||||
)
|
||||
print(f"modal_close = {modal_close}")
|
||||
modal_close.click()
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
# Clear any notice
|
||||
notice_close = WebDriverWait(driver, 2).until(
|
||||
EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div/div[2]/div/div[2]/div/div/div[1]/div[2]/button"))
|
||||
)
|
||||
print(f"notice_close = {notice_close}")
|
||||
notice_close.click()
|
||||
except:
|
||||
pass
|
||||
|
||||
# Enter zip code in the input field and click the "Check" button
|
||||
zip_button = WebDriverWait(driver, 5).until(
|
||||
EC.presence_of_element_located((By.XPATH, '/html/body/div[2]/div/header/div[3]/div/div/div[2]/div[1]'))
|
||||
)
|
||||
zip_button.click()
|
||||
|
||||
zip_input = WebDriverWait(driver, 2).until(
|
||||
EC.presence_of_element_located((By.XPATH, '//div/label/following-sibling::input'))
|
||||
)
|
||||
zip_input.click()
|
||||
zip_input.send_keys("\b\b\b\b\b")
|
||||
zip_input.send_keys(zip_code)
|
||||
|
||||
check_button = driver.find_element(By.XPATH, "//button[text() = 'Confirm']")
|
||||
check_button = WebDriverWait(driver, 2).until(EC.presence_of_element_located((By.XPATH, "//button[text() = 'Confirm']")))
|
||||
check_button.click()
|
||||
|
||||
# Record sales count, if any
|
||||
sales_count_element = get_element_text(driver, 'Header_count')
|
||||
count_start_index = sales_count_element.index('sold ') + len('sold ')
|
||||
count_end_index = sales_count_element.index('+')
|
||||
sales_count = sales_count_element[count_start_index:count_end_index]
|
||||
|
||||
# Record any sold status notice
|
||||
sold_status = get_element_text(driver, 'UnavailableCartbtn_container')
|
||||
if sold_status == 'Notify me':
|
||||
sold_status = 'Sold Out'
|
||||
|
||||
# Extract the price of the product for this zip code
|
||||
min_quantity = 0
|
||||
total_price = 0
|
||||
unit_price = 0
|
||||
try:
|
||||
minimum_quantity_str = driver.find_element(By.XPATH, "//div[contains(@class, 'minQuantity')]")
|
||||
if minimum_quantity_str:
|
||||
regexp = r"Minimum purchase: (\d+) \(\$([\d.]+)"
|
||||
match = re.search(regexp, minimum_quantity_str.get_attribute('innerHTML'))
|
||||
if match:
|
||||
min_quantity, total_price = match.groups()
|
||||
except selenium.common.exceptions.NoSuchElementException:
|
||||
print("No minimum purchase string found")
|
||||
except Exception as e:
|
||||
print(f"Exception when finding minimum purchase string: {e}")
|
||||
|
||||
ld_json_element = driver.find_element(By.XPATH, "//script[@type='application/ld+json']")
|
||||
ld_json_text = ld_json_element.get_attribute('innerHTML')
|
||||
ld_json_start_index = ld_json_text.index('{')
|
||||
ld_json_end_index = ld_json_text.rindex('}') + 1
|
||||
ld_json_json = ld_json_text[ld_json_start_index:ld_json_end_index]
|
||||
ld_json = json.loads(ld_json_json)
|
||||
ld_json_price = ld_json['offers']['price']
|
||||
print(ld_json_price)
|
||||
|
||||
unit_price_element = driver.find_element(By.XPATH, "//div[contains(@class, 'price_price')]")
|
||||
unit_price = unit_price_element.get_attribute('innerText').replace("$", "")
|
||||
print(f"unit_price = {unit_price}")
|
||||
|
||||
subscriber.acknowledge(ack_ids=[message.ack_id], subscription=subscription_path) # acknowledge receipt of message
|
||||
|
||||
new_row = pd.DataFrame({
|
||||
'Product ID': [product_id],
|
||||
'Zip Code': [zip_code],
|
||||
'Shown Price': [ld_json_price],
|
||||
'Minimum Quantity': [min_quantity],
|
||||
'Total Price': [total_price],
|
||||
'Unit Price': [unit_price],
|
||||
'Sales Count': [sales_count],
|
||||
'Sold Status': [sold_status]
|
||||
})
|
||||
return pd.concat([df_new, new_row], ignore_index=True)
|
||||
|
||||
while True:
|
||||
pull_request = pubsub_v1.types.PullRequest(max_messages=1, subscription=subscription_path)
|
||||
messages = []
|
||||
try:
|
||||
pull_response = subscriber.pull(request=pull_request)
|
||||
messages = pull_response.received_messages
|
||||
except DeadlineExceeded:
|
||||
pass
|
||||
|
||||
if messages:
|
||||
df_new = callback(messages[0])
|
||||
print(f"Updated dataframe: {df_new}")
|
||||
else:
|
||||
print(f"No messages, trying again at {time.asctime()}")
|
||||
break
|
||||
|
||||
return df_new
|
||||
|
||||
|
||||
def scrape_multiple_products(project_id, subscription_name, url_list):
|
||||
df_list = []
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
|
||||
futures = []
|
||||
for url in url_list:
|
||||
future = executor.submit(scrape_product_price, project_id, subscription_name, url)
|
||||
futures.append(future)
|
||||
|
||||
for future in concurrent.futures.as_completed(futures):
|
||||
df = future.result()
|
||||
df_list.append(df)
|
||||
print("Scraped data for URL:", url)
|
||||
|
||||
return df_list
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
project_id = input("Enter the project ID: ")
|
||||
subscription_name = input("Enter the subscription name: ")
|
||||
url_list = [
|
||||
'https://www.sayweee.com/en/product/Want-Want-Senbei-Rice-Crackers/17119',
|
||||
'https://www.sayweee.com/en/product/Lays-Potato-Chips-Cucumber-Flavor/51261',
|
||||
'https://www.sayweee.com/en/product/Glico-Pocky-Cookies-and-Cream-Family-Pack/79467',
|
||||
'https://www.sayweee.com/en/product/Xiang-Na-Lan-Thai-Jasmine-Rice/19566?category=dried01',
|
||||
'https://www.sayweee.com/en/product/Sekka-Premium-Japanese-Medium-Grain-Rice/81224',
|
||||
'https://www.sayweee.com/en/product/Big-Green-Spring-Farm-Organic-Millet/90991?category=dried02',
|
||||
'https://www.sayweee.com/en/product/Liuzhou-Guangxi-Specialty-LuoSiFen-Hot-Spicy-Noodles/95442?category=instant01',
|
||||
'https://www.sayweee.com/en/product/House-Foods-Firm-Tofu-/85175?trace_id=c93f3d1a-80a4-4e1a-8d41-a402ae43186f',
|
||||
'https://www.sayweee.com/en/product/Lactaid-Lactose-Free-2--Reduced-Fat-Milk/95353',
|
||||
'https://www.sayweee.com/en/product/Washington-Fuji-Apples/94817?category=fruits03',
|
||||
'https://www.sayweee.com/en/product/Formosa-Pork-Sung-/23528?trace_id=3c143dd4-4a35-4e8d-93ee-d91f209717e7'
|
||||
]
|
||||
|
||||
df_list = scrape_multiple_products(project_id, subscription_name, url_list)
|
||||
|
||||
# Concatenate all dataframes in the list
|
||||
df_combined = pd.concat(df_list, ignore_index=True)
|
||||
|
||||
# Save the combined dataframe to HDF5 file
|
||||
with pd.HDFStore('product1.h5') as store:
|
||||
store.append('key', df_combined, format='table')
|
||||
|
||||
# Print the combined dataframe
|
||||
print("Combined DataFrame:")
|
||||
print(df_combined)
|
||||
|
||||
# Save the combined dataframe to a CSV file
|
||||
df_combined.to_csv('product1.csv', index=False)
|
||||
|
||||
print("Data scraping and storage completed.")
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
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)
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# Question7:
|
||||
# Difference:
|
||||
# 1. Byte objects are sequence of Bytes, whereas Strings are sequence of characters.
|
||||
# 2. Byte objects are in machine readable form internally; Strings are only in human readable form.
|
||||
# 3. strings (str) support various character encodings, such as UTF-8, ASCII, and more. Bytes (bytes), on the other hand, represent raw binary data and can hold any byte values.
|
||||
## Emojis can affect the size difference.
|
||||
import sys
|
||||
string_size = sys.getsizeof("Hello")
|
||||
bytes_size = sys.getsizeof(b"Hello")
|
||||
emoji_size = sys.getsizeof("😀")
|
||||
print(f"String size: {string_size} bytes")
|
||||
print(f"Bytes size: {bytes_size} bytes")
|
||||
print(f"emoji size: {emoji_size} bytes")
|
||||
|
||||
# python routine:
|
||||
def print_string_as_numbers(string):
|
||||
for char in string:
|
||||
print(ord(char))
|
||||
input_string = "Hello, world!"
|
||||
print_string_as_numbers(input_string)
|
||||
@@ -1,38 +0,0 @@
|
||||
# question 8: If the column or data type is invalid, and we take them into calculations without noticing this, wrong number will be produced.
|
||||
# question 9:
|
||||
def read_tomato_sales(file_name):
|
||||
data = pd.read_csv(file_name)
|
||||
if "Tomato_Sales" in data.columns and data["Tomato_Sales"].dtype == "int64":
|
||||
total_sales = data["Tomato_Sales"].sum()
|
||||
print(f"Total tomato sales: {total_sales}")
|
||||
else:
|
||||
raise ValueError("Invalid column or data type.")
|
||||
# question 10: Reasons:
|
||||
# 1. Different languages may have different character encodings, which define how characters are represented
|
||||
# as binary data. By using bytes, you can handle various character encodings, such as UTF-8, UTF-16, or others.
|
||||
# 2. Bytes are language-agnostic and treat text as raw binary data.
|
||||
# 3. Bytes can handle any kind of binary data, including text data in different languages, as well as
|
||||
# non-textual data such as images, audio, or video.
|
||||
def process_multilingual_data(data):
|
||||
# Convert string to bytes using UTF-8 encoding
|
||||
byte_data = data.encode('utf-8')
|
||||
|
||||
# Convert bytes back to string for display or further processing
|
||||
processed_data = byte_data.decode('utf-8')
|
||||
|
||||
return processed_data
|
||||
|
||||
# Example usage
|
||||
text = "This is shunan zhao"
|
||||
processed_text = process_multilingual_data(text)
|
||||
print(processed_text)
|
||||
# 1: ord("😀") gives you the Unicode code point of the character, while 0xf09f9880 represents the byte
|
||||
# sequence in UTF-8 encoding used to represent that character.
|
||||
# 2.5: A REPL is an interactive programming environment that allows you to enter commands or expressions,
|
||||
# which are then evaluated and the results are printed or displayed.
|
||||
# 3: the "_" variable is a special variable that holds the result of the last executed expression or
|
||||
# statement. It is often referred to as the "underscore variable."
|
||||
#The type can vary based on the context and the value assigned to in the current REPL session. For example:
|
||||
# If the last executed expression was an integer, the type of "_" would be int.
|
||||
# If the last executed expression was a string, the type of "_" would be str.
|
||||
# If the last executed expression was a list, the type of "_" would be list.
|
||||
@@ -1,53 +0,0 @@
|
||||
#question 1:
|
||||
# i = 3 Literal Type: Integer, and its value is 3.
|
||||
|
||||
# f = 3.0 Literal Type: Float, and its value is 3.0.
|
||||
|
||||
# c = 3+3j Literal Type: Complex, and its value is 3+3j.
|
||||
|
||||
# b = b'abcdefg' Literal Type: Bytes, and its value is b'abcdefg'.
|
||||
|
||||
# s = 'abcdefg' Literal Type: String, and its value is 'abcdefg'.
|
||||
|
||||
# s = "abcdefg" Literal Type: String, and its value is "abcdefg".
|
||||
|
||||
#question 2:
|
||||
'''
|
||||
'0' b'0' 0 0.0 0j
|
||||
'0' Equal |Not equal |Not equal |Not equal |Not equal
|
||||
b'0'Not equal |Equal |Not equal |Not equal |Not equal
|
||||
0 Not equal |Not equal |Equal |Equal |Equal
|
||||
0.0 Not equal |Not equal |Equal |Equal |Not Equal
|
||||
0j Not equal |Not equal |Equal |Not equal |Equal
|
||||
'''
|
||||
#question 3:
|
||||
##The "+" operator case:
|
||||
'''
|
||||
'0' b'0' 0 0.0 0j
|
||||
'0' '00' |TypeError |TypeError |TypeError |TypeError
|
||||
b'0' TypeError |b'00' |TypeError |TypeError |TypeError
|
||||
0 TypeError |TypeError |0 |0.0 |0j
|
||||
0.0 TypeError |TypeError |0.0 |0.0 |TypeError
|
||||
0j TypeError |TypeError |0j |TypeError |0j
|
||||
'''
|
||||
##The "==" operator case:
|
||||
'''
|
||||
'0' b'0' 0 0.0 0j
|
||||
'0' True |False |False |False |False
|
||||
b'0 False |False |False |False |False
|
||||
0 False |False |False |True |True
|
||||
0.0 False |False |True |True |False
|
||||
0j False |False |True |False |True
|
||||
'''
|
||||
#question4:
|
||||
import ast
|
||||
|
||||
# Open the lexer/parser example file
|
||||
with open('lexer_parser_example.py', 'r') as file:
|
||||
source_code = file.read()
|
||||
|
||||
# Parse the source code into an AST
|
||||
tree = ast.parse(source_code)
|
||||
|
||||
# Dump the AST
|
||||
print(ast.dump(tree, indent=4))
|
||||
@@ -1,34 +0,0 @@
|
||||
# question 5:
|
||||
# The statement print("\007") outputs an ASCII escape sequence \007, which represents the Bell control character. The reason why print("\007")
|
||||
# produces a sound or visual alert is that when the string "\007" is printed, it is interpreted by the terminal or system as a signal to generate
|
||||
# an audible or visual alert, as defined by the specific implementation.
|
||||
|
||||
# question 6:
|
||||
# The code print("abcdefg\rhijklmnop") will output "hijklmnopg"
|
||||
# In Python, the '\r' character is a carriage return character, which instructs the console or terminal to move the cursor back to the beginning
|
||||
# of the current line, without advancing to the next line. This means that anything printed after the '\r' will overwrite whatever was printed earlier
|
||||
# on the same line.
|
||||
|
||||
# question 7:
|
||||
# In this case, the carriage return character \r is treated as a regular character within the response content. It does not have the same effect as
|
||||
# in the previous example where it was used in a print statement.
|
||||
|
||||
# qustion 8:
|
||||
# If a hacker attacks a credit card system. When the customer came to buy a can of Coke, he paid 2 knives to the store, but the display in the
|
||||
# background was "2/r500".
|
||||
|
||||
# question 9:
|
||||
def validate(input_string):
|
||||
if "\r" in input_string:
|
||||
raise ValueError("Crime detected!")
|
||||
try:
|
||||
validate("abcdefg")
|
||||
print("✅ test1 pass!")
|
||||
except:
|
||||
print("❌ test1 fail!")
|
||||
|
||||
try:
|
||||
validate("abcdefg\rhijklmnop")
|
||||
print("❌ test2 fail!")
|
||||
except ValueError as err:
|
||||
print("✅ test2 pass!")
|
||||
@@ -1,77 +0,0 @@
|
||||
class BoundedInt():
|
||||
def __init__(self, i, min_val, max_val):
|
||||
self.i = i
|
||||
self.min = min_val
|
||||
self.max = max_val
|
||||
|
||||
def __int__(self):
|
||||
return self.i
|
||||
|
||||
def __sub__(self, other):
|
||||
if isinstance(other, BoundedInt):
|
||||
result = self.i - other.i
|
||||
else:
|
||||
result = self.i - other
|
||||
if result < self.min:
|
||||
raise ValueError("Result exceeds min value")
|
||||
return BoundedInt(result, self.min, self.max)
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, BoundedInt):
|
||||
result = self.i + other.i
|
||||
else:
|
||||
result = self.i + other
|
||||
if result > self.max:
|
||||
raise ValueError("Result exceeds max value")
|
||||
return BoundedInt(result, self.min, self.max)
|
||||
|
||||
def test1(self):
|
||||
bi1 = BoundedInt(0xdeadbeef, min_val=(0xdeadbeef - 1), max_val=(0xdeadbeef + 1))
|
||||
if int(bi1) == 0xdeadbeef:
|
||||
print(f"✅ Test 1 passed!")
|
||||
else:
|
||||
print(f"❌ Test 1 failed, int(bi1) = {int(bi1)}, expected 0xdeadbeef")
|
||||
|
||||
def test2(self):
|
||||
bi2 = BoundedInt(1, min_val=0, max_val=1)
|
||||
bi3 = BoundedInt(1, min_val=0, max_val=1)
|
||||
try:
|
||||
bi4 = bi2 + bi3 # 1 + 1 = 2, which exceeds max_val = 1
|
||||
print(f"❌ Test 2 failed!")
|
||||
except ValueError as err:
|
||||
print(f"✅ Test 2 passed!")
|
||||
|
||||
def test3(self):
|
||||
bi4 = BoundedInt(1, min_val=0, max_val=1)
|
||||
bi5 = BoundedInt(2, min_val=0, max_val=-1)
|
||||
try:
|
||||
bi6 = bi4 - bi5 # 1 - 2 = -1, which is less than min_val = 0
|
||||
print(f"❌ Test 3 failed!")
|
||||
except ValueError as err:
|
||||
print(f"✅ Test 3 passed!")
|
||||
|
||||
def test4(self):
|
||||
bi7 = BoundedInt(1, min_val=0, max_val=1)
|
||||
bi8 = 2
|
||||
try:
|
||||
bi9 = bi7 + bi8
|
||||
print(f"❌ Test 4 failed!")
|
||||
except ValueError as err:
|
||||
print(f"✅ Test 4 passed!")
|
||||
|
||||
def test5(self):
|
||||
bi10 = BoundedInt(1, min_val=0, max_val=1)
|
||||
bi11 = 2
|
||||
try:
|
||||
bi12 = bi10 - 11
|
||||
print(f"❌ Test 5 failed!")
|
||||
except ValueError as err:
|
||||
print(f"✅ Test 5 passed!")
|
||||
|
||||
|
||||
tester = BoundedInt(0, 0, 0)
|
||||
tester.test1()
|
||||
tester.test2()
|
||||
tester.test3()
|
||||
tester.test4()
|
||||
tester.test5()
|
||||
@@ -1,118 +0,0 @@
|
||||
# question 1:
|
||||
#boolean context:
|
||||
#In programming, a boolean context refers to a situation where a condition or expression is evaluated as either true or false.
|
||||
#A boolean context typically occurs in control flow statements, such as if statements or while loops, where the condition determines whether
|
||||
#a certain block of code should be executed or repeated.
|
||||
|
||||
#Ellipsis:
|
||||
#an ellipsis (...) is a special token that represents an ellipsis object. It is often used as a placeholder in code or data structures where
|
||||
#you intend to fill in additional functionality or content later.
|
||||
|
||||
#machine-level double precision floating point numbers
|
||||
#Machine-level double precision floating-point numbers, often referred to as double, are a common representation of real numbers in computer systems.
|
||||
#They are a binary format used to store and manipulate floating-point values with higher precision compared to single precision.
|
||||
|
||||
#Callable types:
|
||||
#callable types refer to objects that can be called as functions. These objects are capable of executing code when invoked with parentheses, just
|
||||
#like a regular function.
|
||||
|
||||
#cell_contents:
|
||||
#the term "cell contents" refers to the value stored in a cell of a closure. A closure is a function object that retains references to variables
|
||||
#in its enclosing lexical scope, even when the outer function has finished executing.
|
||||
#When a closure is created, each variable it references is stored in a cell, which is an internal data structure associated with the closure.
|
||||
#The cell contents refer to the value stored within the cell associated with a particular variable in a closure. It represents the value of the
|
||||
#variable as seen by the closure, regardless of any changes made to the variable in the outer scope.
|
||||
|
||||
#example for "When an instance method object is created by retrieving a user-defined function object from a class via one of its instances,
|
||||
#its __self__ attribute is the instance, and the method object is said to be bound. The new method’s __func__ attribute is the original function
|
||||
#object."
|
||||
"""""
|
||||
class MyClass:
|
||||
def my_method(self):
|
||||
print("Hello, world!")
|
||||
|
||||
# Creating an instance of MyClass
|
||||
my_instance = MyClass()
|
||||
|
||||
# Retrieving the method object from the instance
|
||||
method_object = my_instance.my_method
|
||||
|
||||
# Accessing the attributes of the method object
|
||||
print(method_object.__self__) # Output: <__main__.MyClass object at 0x...>
|
||||
print(method_object.__func__) # Output: <function MyClass.my_method at 0x...>
|
||||
|
||||
# Calling the method through the method object
|
||||
method_object() # Output: Hello, world!
|
||||
"""""
|
||||
|
||||
#async def:
|
||||
# the async def syntax is used to define an asynchronous function, also known as a coroutine. An asynchronous function allows concurrent
|
||||
# execution of multiple tasks by allowing the program to proceed to other tasks while waiting for certain operations to complete.
|
||||
"""""
|
||||
import asyncio
|
||||
|
||||
async def my_coroutine():
|
||||
print("Coroutine started")
|
||||
await asyncio.sleep(1) # Simulating an asynchronous operation
|
||||
print("Coroutine completed")
|
||||
|
||||
# Calling the coroutine
|
||||
asyncio.run(my_coroutine())
|
||||
"""""
|
||||
#Static method and class method:
|
||||
#In Python, static methods and class methods are two types of methods that can be defined within a class.
|
||||
#Static methods:
|
||||
#Static methods are defined using the @staticmethod decorator or by declaring them inside the class without any special decorator.
|
||||
#Static methods are not bound to a specific instance or the class itself. They behave like regular functions but are defined within the class for organizational purposes.
|
||||
#Static methods do not have access to the instance or class attributes and cannot modify them directly.
|
||||
#Static methods can be called on the class itself or on an instance of the class.
|
||||
#Class methods:
|
||||
#Class methods are defined using the @classmethod decorator.
|
||||
#Class methods are bound to the class itself rather than the instances. They receive the class as the first argument (usually named cls) instead of the instance (self).
|
||||
#Class methods have access to the class attributes and can modify them if needed.
|
||||
#Class methods can be called on the class itself or on an instance of the class.
|
||||
|
||||
# question 2:
|
||||
def add_numbers(a, b):
|
||||
result = a + b
|
||||
return result
|
||||
|
||||
def multiply_numbers(x, y):
|
||||
result = x * y
|
||||
return result
|
||||
|
||||
def main():
|
||||
number1 = 5
|
||||
number2 = 10
|
||||
sum_result = add_numbers(number1, number2)
|
||||
breakpoint() # Set breakpoint here
|
||||
product_result = multiply_numbers(sum_result, number2)
|
||||
print("Product:", product_result)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
# question 3:
|
||||
|
||||
def calculate_square(x):
|
||||
square = x ** 2
|
||||
return square
|
||||
|
||||
def calculate_cube(x):
|
||||
cube = x ** 3
|
||||
return cube
|
||||
|
||||
def main():
|
||||
number = 5
|
||||
breakpoint() # Set breakpoint here
|
||||
square_result = calculate_square(number)
|
||||
cube_result = calculate_cube(number)
|
||||
print("Square:", square_result)
|
||||
print("Cube:", cube_result)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
PS C:\Users\Maxzh\python-bootcamp\max submission> python .\6_9_HW.py
|
||||
> c:\users\maxzh\python-bootcamp\max submission\6_9_hw.py(89)main()
|
||||
-> product_result = multiply_numbers(sum_result, number2)
|
||||
(Pdb) next
|
||||
> c:\users\maxzh\python-bootcamp\max submission\6_9_hw.py(90)main()
|
||||
-> print("Product:", product_result)
|
||||
(Pdb) c
|
||||
Product: 150
|
||||
> c:\users\maxzh\python-bootcamp\max submission\6_9_hw.py(108)main()
|
||||
-> square_result = calculate_square(number)
|
||||
(Pdb) next
|
||||
> c:\users\maxzh\python-bootcamp\max submission\6_9_hw.py(109)main()
|
||||
-> cube_result = calculate_cube(number)
|
||||
(Pdb) c
|
||||
Square: 25
|
||||
Cube: 125
|
||||
PS C:\Users\Maxzh\python-bootcamp\max submission> python .\6_9_HW.py
|
||||
> c:\users\maxzh\python-bootcamp\max submission\6_9_hw.py(89)main()
|
||||
-> product_result = multiply_numbers(sum_result, number2)
|
||||
(Pdb) step
|
||||
--Call--
|
||||
> c:\users\maxzh\python-bootcamp\max submission\6_9_hw.py(80)multiply_numbers()
|
||||
-> def multiply_numbers(x, y):
|
||||
(Pdb) c
|
||||
Product: 150
|
||||
> c:\users\maxzh\python-bootcamp\max submission\6_9_hw.py(108)main()
|
||||
-> square_result = calculate_square(number)
|
||||
(Pdb) step
|
||||
--Call--
|
||||
> c:\users\maxzh\python-bootcamp\max submission\6_9_hw.py(97)calculate_square()
|
||||
-> def calculate_square(x):
|
||||
(Pdb) c
|
||||
Square: 25
|
||||
Cube: 125
|
||||
@@ -1,21 +0,0 @@
|
||||
# question 1: The international standard for floating-point representation is called IEEE 754.
|
||||
|
||||
# question 2: The IEEE 754 standard allows floating-point numbers to be represented with different bit sizes. The most commonly used formats specified by the standard are single precision (32 bits) and double precision (64 bits).
|
||||
|
||||
# question 3:
|
||||
import sys
|
||||
print(sys.float_info)
|
||||
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
|
||||
|
||||
# question 4: In the first multiplication (num1 * num2), you are using the normal Python multiplication
|
||||
# operator, which operates on native Python integers. Python integers have arbitrary precision, meaning they can
|
||||
# represent very large numbers accurately. However, when the result exceeds the limit of a 64-bit signed integer
|
||||
# (2^63 - 1), an overflow may occur, and the result may not be accurate.
|
||||
# In the second multiplication (df['Number1'] * df['Number2']), you are using the Pandas multiplication operator
|
||||
# on the columns of a DataFrame. By default, Pandas uses NumPy for numerical computations, and NumPy uses
|
||||
# fixed-size data types. In this case, the integers in the DataFrame are most likely represented as 64-bit
|
||||
# signed integers (int64), which have a maximum value of 2^63 - 1. If the result of the multiplication exceeds
|
||||
# this limit, it will overflow and wrap around, leading to incorrect results.
|
||||
|
||||
# Question5: 5. The size of a Python floating-point number is determined by the implementation and is not influenced by the magnitude of the value it represents. So it does not change as the value of the number gets larger.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCbUrTPE/8CUByUtG9rBuMP5zeF3x5sZcPmm61bcxBblvHL5Dx1WwIjujhbZ5mhxnmDqxV07MCFZwMzlPjJ7Ow9erZvaXAe5+jS2iTQqu9apfj+U3x2xEZQmoKprXUpWl8G9YDk2wxBqCn//ugkJ5+erIEopNUGPcVhACucpaCT+kld9mHtXBjdUEKUA85HhXiBkuBsv9k/VqL/oXbvHjY8Z6gFP64LcxdNASuf4Qn1wW0w3kXlQRkSoGdSxpGLztXN1v5rvetOzjA8HXixh7TYVWCc+XCa9KsY3QRk7gFyvtIsXz59NMOTgfpCnUQE2Pk9R5wuuA2fXyr+Kg+7NPkd sloetjeswong@Sloetjess-Air
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Users Table</title>
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Username</th>
|
||||
<th>Credentials</th>
|
||||
<th>Creation Date</th>
|
||||
<th>Modification Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>{{ user.id }}</td>
|
||||
<td>{{ user.username }}</td>
|
||||
<td>{{ user.credentials }}</td>
|
||||
<td>{{ user.creation_date }}</td>
|
||||
<td>{{ user.modification_date }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user