-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfilter.py
More file actions
executable file
·181 lines (153 loc) · 5.15 KB
/
filter.py
File metadata and controls
executable file
·181 lines (153 loc) · 5.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/usr/bin/env python3
"""
Filter properties by area, price, beds, etc.
Usage:
python3 filter.py <properties.json> [options]
Options:
--areas EH10,EH12,EH4 Desired postcodes/areas
--exclude EH17,Niddrie Areas to exclude
--min-price 300000 Minimum price
--max-price 600000 Maximum price
--min-beds 4 Minimum bedrooms
--category family Category filter
"""
import json
import sys
import argparse
from typing import List, Dict, Any
# Edinburgh area configuration
DESIRED_AREAS = [
'EH10', # Morningside
'EH12', # Corstorphine
'EH13', # Oxgangs, Colinton
'EH14', # Juniper Green, Colinton
'EH4', # Davidson's Mains, Cramond
'EH5', # Leith
'EH6', # Leith
'EH15', # Portobello, Joppa
'EH3', # Stockbridge
'EH9', # Marchmont, Bruntsfield
]
EXCLUDED_AREAS = [
'EH17', # Liberton (some areas)
'Moredun',
'Niddrie',
'Wester Hailes',
'Sighthill',
'Muirhouse',
'Pilton',
'Granton',
'EH29', # Kirkliston
]
def filter_properties(
properties: List[Dict[str, Any]],
areas: List[str] = None,
exclude: List[str] = None,
min_price: int = None,
max_price: int = None,
min_beds: int = None,
category: str = None
) -> List[Dict[str, Any]]:
"""
Filter properties by criteria.
Args:
properties: List of property dicts
areas: Desired areas/postcodes (case-insensitive partial match)
exclude: Areas to exclude (case-insensitive partial match)
min_price: Minimum price
max_price: Maximum price
min_beds: Minimum bedrooms
category: Category filter (investment, family, other)
Returns:
Filtered list of properties
"""
filtered = properties
# Area filtering
if areas:
areas_lower = [a.lower() for a in areas]
filtered = [
p for p in filtered
if any(area in p.get('address', '').lower() or area in p.get('postcode', '').lower()
for area in areas_lower)
]
# Exclude areas
if exclude:
exclude_lower = [e.lower() for e in exclude]
filtered = [
p for p in filtered
if not any(excl in p.get('address', '').lower() or excl in p.get('postcode', '').lower()
for excl in exclude_lower)
]
# Price filtering
if min_price is not None:
filtered = [p for p in filtered if p.get('price', 0) >= min_price]
if max_price is not None:
filtered = [p for p in filtered if p.get('price', 0) <= max_price]
# Bedroom filtering
if min_beds is not None:
filtered = [p for p in filtered if p.get('beds', 0) >= min_beds]
# Category filtering
if category:
filtered = [p for p in filtered if p.get('category') == category]
return filtered
def main():
parser = argparse.ArgumentParser(description='Filter properties')
parser.add_argument('input_file', help='Input JSON file')
parser.add_argument('--areas', help='Desired areas (comma-separated)')
parser.add_argument('--exclude', help='Areas to exclude (comma-separated)')
parser.add_argument('--min-price', type=int, help='Minimum price')
parser.add_argument('--max-price', type=int, help='Maximum price')
parser.add_argument('--min-beds', type=int, help='Minimum bedrooms')
parser.add_argument('--category', choices=['investment', 'family', 'other'], help='Category filter')
parser.add_argument('--use-defaults', action='store_true', help='Use default Edinburgh areas')
args = parser.parse_args()
# Load properties
try:
with open(args.input_file) as f:
data = json.load(f)
properties = data.get('properties', data) if isinstance(data, dict) else data
except Exception as e:
print(f"Error loading {args.input_file}: {e}", file=sys.stderr)
sys.exit(1)
# Parse areas
areas = None
if args.use_defaults:
areas = DESIRED_AREAS
elif args.areas:
areas = [a.strip() for a in args.areas.split(',')]
exclude = None
if args.use_defaults:
exclude = EXCLUDED_AREAS
elif args.exclude:
exclude = [e.strip() for e in args.exclude.split(',')]
# Filter
original_count = len(properties)
filtered = filter_properties(
properties,
areas=areas,
exclude=exclude,
min_price=args.min_price,
max_price=args.max_price,
min_beds=args.min_beds,
category=args.category
)
# Output
result = {
'filtering': {
'original_count': original_count,
'filtered_count': len(filtered),
'removed_count': original_count - len(filtered),
'criteria': {
'areas': areas,
'exclude': exclude,
'min_price': args.min_price,
'max_price': args.max_price,
'min_beds': args.min_beds,
'category': args.category
}
},
'properties': filtered
}
print(json.dumps(result, indent=2))
if __name__ == '__main__':
main()