· 6 years ago · Apr 06, 2020, 04:42 PM
1#
2# In order to solve the problems below you can import any standard
3# python3 library.
4#
5# If you don't know Python, implement it in any other language.
6#
7# Good luck!
8#
9
10
11############
12#
13# Cheap Crowdfunding Problem
14#
15# There is a crowdfunding project that you want to support. This project
16# gives the same reward to every supporter, with one peculiar condition:
17# the amount you pledge must not be equal to any earlier pledge amount.
18#
19# You would like to get the reward, while spending the least amount > 0.
20#
21# You are given a list of amounts pledged so far in an array of integers.
22# You know that there is less than 100,000 of pledges and the maximum
23# amount pledged is less than $1,000,000.
24#
25# Implement a function find_min_pledge(pledge_list) that will return
26# the amount you should pledge.
27#
28############
29
30def find_min_pledge(pledge_list):
31 pass
32
33assert find_min_pledge([1, 3, 6, 4, 1, 2]) == 5
34
35assert find_min_pledge([1, 2, 3]) == 4
36
37assert find_min_pledge([-1, -3]) == 1
38
39
40############
41#
42# Extract Titles from RSS feed
43#
44# Implement get_headlines() function. It should take a url of an RSS feed
45# and return a list of strings representing article titles.
46#
47############
48
49google_news_url="https://news.google.com/news/rss"
50
51
52def get_headlines(rss_url):
53 """
54 @returns a list of titles from the rss feed located at `rss_url`
55 """
56 return []
57
58print(get_headlines(google_news_url))
59
60
61
62############
63#
64# Streaming Payments Processor
65#
66# The function `process_payments()` is processing a large, but finite
67# amount of payments in a streaming fashion.
68#
69# It relies on two library functions to do its job. The first function
70# `stream_payments_to_storage(storage)` reads the payments from a payment
71# processor and writes them to storage by calling `storage.write(buffer)`
72# on it's `storage` argument. The `storage` argument is supplied by
73# calling `get_payments_storage()` function. The API is defined below.
74#
75# TODO: Modify `process_payments()` to print a checksum of bytes written
76# by `stream_payments_to_storage()`. The existing functionality
77# should be preserved.
78#
79# The checksum is implemented as a simple arithmetic sum of bytes.
80#
81# For example, if bytes([1, 2, 3]) were written, you should print 6.
82#
83#
84# NOTE: you need to take into account the following restrictions:
85# - You are allowed only one call each to `get_payments_storage()` and
86# to `stream_payments_to_storage()`
87# - You can not read from the storage.
88# - You can not use disk as temporary storage.
89# - Your system has limited memory that can not hold all payments.
90#
91############
92
93
94# This is a library function, you can't modify it.
95def get_payments_storage():
96 """
97 @returns an instance of
98 https://docs.python.org/3/library/io.html#io.BufferedWriter
99 """
100 # Sample implementation to make the code run in coderpad.
101 # Do not rely on this exact implementation.
102 return open('/dev/null', 'wb')
103
104
105# This is a library function, you can't modify it.
106def stream_payments_to_storage(storage):
107 """
108 Loads payments and writes them to the `storage`.
109 Returns when all payments have been written.
110
111 @parameter `storage`: is an instance of
112 https://docs.python.org/3/library/io.html#io.BufferedWriter
113 """
114 # Sample implementation to make the code run in coderpad.
115 # Do not rely on this exact implementation.
116 for i in range(10):
117 storage.write(bytes([1, 2, 3, 4, 5]))
118
119
120def process_payments():
121 """
122 TODO:
123 Modify `process_payments()` to print the checksum of data
124 generated by the `stream_payments_to_storage()` call.
125 """
126 stream_payments_to_storage(get_payments_storage())
127 # Here print the check sum of all of the bytes written by
128 # `stream_payments_to_storage()`
129
130process_payments()
131
132
133############
134# Streaming Payments Processor, two vendors edition.
135#
136# We decided to improve the payment processor from the previous
137# exercise and hired two vendors. One was to implement `stream_payments()`
138# function, and another `store_payments()` function.
139#
140# The function `process_payments_2()` is processing a large, but finite
141# amount of payments in a streaming fashion.
142#
143# Unfortunately the vendors did not coordinate their efforts, and delivered
144# their functions with incompatible APIs.
145#
146# TODO: Your task is to analyse the APIs of `stream_payments()` and
147# `store_payments()` and to write glue code in `process_payments_2()`
148# that allows us to store the payments using these vendor functions.
149#
150# NOTE: you need to take into account the following restrictions:
151# - You are allowed only one call each to `stream_payments()` and
152# to `store_payments()`
153# - You can not read from the storage.
154# - You can not use disk as temporary storage.
155# - Your system has limited memory that can not hold all payments.
156#
157############
158
159import io
160
161
162# This is a library function, you can't modify it.
163def stream_payments(callback_fn):
164 """
165 Reads payments from a payment processor and calls `callback_fn(amount)`
166 for each payment.
167
168 Returns when there is no more payments.
169 """
170 # Sample implementation to make the code run in coderpad.
171 # Do not rely on this exact implementation.
172 for i in range(10):
173 callback_fn(i)
174
175
176# This is a library function, you can't modify it.
177def store_payments(amount_iterator):
178 """
179 Iterates over the payment amounts from amount_iterator
180 and stores them to a remote system.
181 """
182 # Sample implementation to make the code run in coderpad.
183 # Do not rely on this exact implementation.
184 for i in amount_iterator:
185 print(i)
186
187
188def callback_example(amount):
189 print(amount)
190 return True
191
192
193def process_payments_2():
194 """
195 TODO:
196 Modify `process_payments_2()`, write glue code that enables
197 `store_payments()` to consume payments produced by `stream_payments()`
198 """
199 stream_payments(callback_example)
200
201
202process_payments_2()
203
204
205############
206#
207# Code Review
208#
209# Please do a code review for the following snippet.
210# Add your review suggestions inline as python comments
211#
212############
213
214
215def get_value(data, key, default, lookup=None, mapper=None):
216 """
217 Finds the value from data associated with key, or default if the
218 key isn't present.
219 If a lookup enum is provided, this value is then transformed to its
220 enum value.
221 If a mapper function is provided, this value is then transformed
222 by applying mapper to it.
223 """
224 return_value = data[key]
225 if return_value is None or return_value == "":
226 return_value = default
227 if lookup:
228 return_value = lookup[return_value]
229 if mapper:
230 return_value = mapper(return_value)
231 return return_value
232
233
234def ftp_file_prefix(namespace):
235 """
236 Given a namespace string with dot-separated tokens, returns the
237 string with
238 the final token replaced by 'ftp'.
239 Example: a.b.c => a.b.ftp
240 """
241 return ".".join(namespace.split(".")[:-1]) + '.ftp'
242
243
244def string_to_bool(string):
245 """
246 Returns True if the given string is 'true' case-insensitive,
247 False if it is
248 'false' case-insensitive.
249 Raises ValueError for any other input.
250 """
251 if string.lower() == 'true':
252 return True
253 if string.lower() == 'false':
254 return False
255 raise ValueError(f'String {string} is neither true nor false')
256
257
258def config_from_dict(dict):
259 """
260 Given a dict representing a row from a namespaces csv file,
261 returns a DAG configuration as a pair whose first element is the
262 DAG name
263 and whose second element is a dict describing the DAG's properties
264 """
265 namespace = dict['Namespace']
266 return (dict['Airflow DAG'],
267 {"earliest_available_delta_days": 0,
268 "lif_encoding": 'json',
269 "earliest_available_time":
270 get_value(dict, 'Available Start Time', '07:00'),
271 "latest_available_time":
272 get_value(dict, 'Available End Time', '08:00'),
273 "require_schema_match":
274 get_value(dict, 'Requires Schema Match', 'True',
275 mapper=string_to_bool),
276 "schedule_interval":
277 get_value(dict, 'Schedule', '1 7 * * * '),
278 "delta_days":
279 get_value(dict, 'Delta Days', 'DAY_BEFORE',
280 lookup=DeltaDays),
281 "ftp_file_wildcard":
282 get_value(dict, 'File Naming Pattern', None),
283 "ftp_file_prefix":
284 get_value(dict, 'FTP File Prefix',
285 ftp_file_prefix(namespace)),
286 "namespace": namespace
287 }
288 )