Skip to content

Commit a73d13e

Browse files
committed
initial commit
0 parents  commit a73d13e

File tree

11 files changed

+946
-0
lines changed

11 files changed

+946
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# This workflow will upload a Python Package using Twine when a release is created
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3+
4+
# This workflow uses actions that are not certified by GitHub.
5+
# They are provided by a third-party and are governed by
6+
# separate terms of service, privacy policy, and support
7+
# documentation.
8+
9+
name: Upload Python Package
10+
11+
on:
12+
release:
13+
types: [published]
14+
15+
permissions:
16+
contents: read
17+
18+
jobs:
19+
deploy:
20+
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- uses: actions/checkout@v4
25+
26+
- name: Install uv
27+
uses: astral-sh/setup-uv@v6
28+
29+
- name: Build Project
30+
run: |
31+
uv sync
32+
uv build
33+
- name: Publish package
34+
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
35+
with:
36+
user: __token__
37+
password: ${{ secrets.PYPI_API_TOKEN }}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3+
4+
name: Python testing
5+
6+
on:
7+
push:
8+
branches: [ "main" ]
9+
pull_request:
10+
branches: [ "main" ]
11+
12+
jobs:
13+
build:
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
os: [macos-latest, windows-latest, ubuntu-latest]
18+
runs-on: ${{ matrix.os }}
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- name: Install uv
23+
uses: astral-sh/setup-uv@v6
24+
25+
- name: Install dependencies
26+
run: |
27+
uv sync
28+
- name: Test black formatted
29+
run: |
30+
uv run black src --check
31+
- name: Test with pytest
32+
run: |
33+
uv run pytest

.gitignore

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Project related
2+
Examples/*/models/*
3+
4+
# Byte-compiled / optimized / DLL files
5+
__pycache__/
6+
*.py[cod]
7+
*$py.class
8+
9+
# C extensions
10+
*.so
11+
12+
# Distribution / packaging
13+
.Python
14+
build/
15+
develop-eggs/
16+
dist/
17+
downloads/
18+
eggs/
19+
.eggs/
20+
lib/
21+
lib64/
22+
parts/
23+
sdist/
24+
var/
25+
wheels/
26+
pip-wheel-metadata/
27+
share/python-wheels/
28+
*.egg-info/
29+
.installed.cfg
30+
*.egg
31+
MANIFEST
32+
33+
# PyInstaller
34+
# Usually these files are written by a python script from a template
35+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
36+
*.manifest
37+
*.spec
38+
39+
# Installer logs
40+
pip-log.txt
41+
pip-delete-this-directory.txt
42+
43+
# Unit test / coverage reports
44+
htmlcov/
45+
.tox/
46+
.nox/
47+
.coverage
48+
.coverage.*
49+
.cache
50+
nosetests.xml
51+
coverage.xml
52+
*.cover
53+
*.py,cover
54+
.hypothesis/
55+
.pytest_cache/
56+
57+
# Translations
58+
*.mo
59+
*.pot
60+
61+
# Django stuff:
62+
*.log
63+
local_settings.py
64+
db.sqlite3
65+
db.sqlite3-journal
66+
67+
# Flask stuff:
68+
instance/
69+
.webassets-cache
70+
71+
# Scrapy stuff:
72+
.scrapy
73+
74+
# Sphinx documentation
75+
docs/_build/
76+
77+
# PyBuilder
78+
target/
79+
80+
# Jupyter Notebook
81+
.ipynb_checkpoints
82+
83+
# IPython
84+
profile_default/
85+
ipython_config.py
86+
87+
# pyenv
88+
.python-version
89+
90+
# pipenv
91+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
93+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
94+
# install all needed dependencies.
95+
#Pipfile.lock
96+
97+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
98+
__pypackages__/
99+
100+
# Celery stuff
101+
celerybeat-schedule
102+
celerybeat.pid
103+
104+
# SageMath parsed files
105+
*.sage.py
106+
107+
# Environments
108+
.env
109+
.venv
110+
env/
111+
venv/
112+
ENV/
113+
env.bak/
114+
venv.bak/
115+
116+
# Spyder project settings
117+
.spyderproject
118+
.spyproject
119+
120+
# Rope project settings
121+
.ropeproject
122+
123+
# mkdocs documentation
124+
/site
125+
126+
# mypy
127+
.mypy_cache/
128+
.dmypy.json
129+
dmypy.json
130+
131+
# Pyre type checker
132+
.pyre/
133+
Examples/Example 2/models/CB0.0.toml

README.md

Whitespace-only changes.

pyproject.toml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[project]
2+
name = "loadbearing-wall"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
authors = [
7+
{ name = "Connor Ferster", email = "connorferster@gmail.com" }
8+
]
9+
requires-python = ">=3.13"
10+
dependencies = [
11+
"load-distribution>=0.1.0",
12+
]
13+
14+
[project.scripts]
15+
loadbearing-wall = "loadbearing_wall:main"
16+
17+
[build-system]
18+
requires = ["hatchling"]
19+
build-backend = "hatchling.build"
20+
21+
[dependency-groups]
22+
dev = [
23+
"black>=25.1.0",
24+
"pytest>=8.4.1",
25+
]

src/loadbearing_wall/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def main() -> None:
2+
print("Hello from loadbearing-wall!")

src/loadbearing_wall/geom_ops.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import math
2+
from typing import Optional
3+
4+
def apply_spread_angle(
5+
wall_height: float,
6+
wall_length: float,
7+
spread_angle: float,
8+
w0: float,
9+
x0: float,
10+
w1: Optional[float] = None,
11+
x1: Optional[float] = None,
12+
) -> dict:
13+
"""
14+
Returns a dictionary representing the load described by
15+
w0, w1, x0, x1. If only w0 and x0 are provided, the
16+
load is assumed to be a point load.
17+
18+
The total spread cannot be longer than the wall length.
19+
20+
spread_angle is assumed to be in degrees
21+
"""
22+
angle_rads = math.radians(spread_angle)
23+
spread_amount = wall_height * math.tan(angle_rads)
24+
projected_x0 = max(0.0, x0 - spread_amount)
25+
if x1 is None:
26+
projected_x1 = min(wall_length, x0 + spread_amount)
27+
else:
28+
projected_x1 = min(wall_length, x1 + spread_amount)
29+
projected_length = projected_x1 - projected_x0
30+
assert projected_length <= wall_length
31+
original_length = x1 - x0
32+
ratio = original_length / projected_length
33+
projected_w0 = w0 * ratio
34+
projected_w1 = w1 * ratio
35+
assert (projected_w0 + projected_w1) / 2 * projected_length == (w0 + w1) / 2 * original_length
36+
return (projected_w0, projected_w1, projected_x0, projected_x1)

0 commit comments

Comments
 (0)