| 1 | package fr.sii.ogham.testing.helper.email; | |
| 2 | ||
| 3 | import java.io.IOException; | |
| 4 | import java.io.InputStream; | |
| 5 | import java.nio.charset.Charset; | |
| 6 | import java.util.ArrayList; | |
| 7 | import java.util.List; | |
| 8 | import java.util.regex.Pattern; | |
| 9 | ||
| 10 | import javax.mail.Address; | |
| 11 | import javax.mail.BodyPart; | |
| 12 | import javax.mail.Message; | |
| 13 | import javax.mail.Message.RecipientType; | |
| 14 | import javax.mail.MessagingException; | |
| 15 | import javax.mail.Multipart; | |
| 16 | import javax.mail.Part; | |
| 17 | ||
| 18 | import org.apache.commons.io.IOUtils; | |
| 19 | import org.junit.Assert; | |
| 20 | import org.junit.ComparisonFailure; | |
| 21 | ||
| 22 | import fr.sii.ogham.testing.helper.html.AssertHtml; | |
| 23 | ||
| 24 | /** | |
| 25 | * Utility class for checking if the received email content is as expected. | |
| 26 | * | |
| 27 | * @author Aurélien Baudet | |
| 28 | * | |
| 29 | */ | |
| 30 | @SuppressWarnings("squid:S1192") | |
| 31 | public final class AssertEmail { | |
| 32 | private static final Pattern HTML_PATTERN = Pattern.compile("<html", Pattern.CASE_INSENSITIVE); | |
| 33 | private static final Pattern TEXT_OR_HTML_MIMETYPES = Pattern.compile("^((text/)|(application/x?html)).*", Pattern.CASE_INSENSITIVE); | |
| 34 | ||
| 35 | /** | |
| 36 | * Assert that the fields of the received email are equal to the expected | |
| 37 | * values. The expected email contains several parts (several contents). The | |
| 38 | * received email should also have the equivalent parts. It will check that: | |
| 39 | *
 | |
| 40 | *
The received headers are respected (see | |
| 41 | * {@link #assertHeaders(ExpectedEmailHeader, Message)})
 | |
| 42 | *
The received message is a {@link Multipart} email
 | |
| 43 | *
The number of parts are equal
 | |
| 44 | *
Each received part body equals the expected one (order is important). | |
| 45 | * See {@link #assertBody(String, String, boolean)}
 | |
| 46 | *
Each received part Mime Type equals the expected one (order is | |
| 47 | * important). See {@link #assertMimetype(ExpectedContent, String)}
 | |
| 48 | *
 | |
| 49 | *
 | |
| 50 | * The checking of the body is done strictly (totally equal). | |
| 51 | *
 | |
| 52 | * | |
| 53 | * @param expectedEmail | |
| 54 | * all the fields with their expected values | |
| 55 | * @param actualEmail | |
| 56 | * the received email | |
| 57 | * @throws MessagingException | |
| 58 | * when accessing the received email fails | |
| 59 | * @throws IOException | |
| 60 | * when reading the content of the email fails | |
| 61 | */ | |
| 62 | public static void assertEquals(ExpectedMultiPartEmail expectedEmail, Message actualEmail) throws MessagingException, IOException { | |
| 63 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertEquals → NO_COVERAGE |
assertEquals(expectedEmail, actualEmail, true); |
| 64 | } | |
| 65 | ||
| 66 | /** | |
| 67 | *
 | |
| 68 | * Shortcut to simplify unit testing with GreenMail. See | |
| 69 | * {@link #assertEquals(ExpectedMultiPartEmail[], Message[])}. | |
| 70 | *
 | |
| 71 | * Assert that the fields of the received email are equal to the expected | |
| 72 | * values. The expected email contains several parts (several contents). The | |
| 73 | * received email should also have the equivalent parts. It will check that: | |
| 74 | *
 | |
| 75 | *
The received headers are respected (see | |
| 76 | * {@link #assertHeaders(ExpectedEmailHeader, Message)})
 | |
| 77 | *
The received message is a {@link Multipart} email
 | |
| 78 | *
The number of parts are equal
 | |
| 79 | *
Each received part body equals the expected one (order is important). | |
| 80 | * See {@link #assertBody(String, String, boolean)}
 | |
| 81 | *
Each received part Mime Type equals the expected one (order is | |
| 82 | * important). See {@link #assertMimetype(ExpectedContent, String)}
 | |
| 83 | *
 | |
| 84 | *
 | |
| 85 | * The checking of the body is done strictly (totally equal). | |
| 86 | *
 | |
| 87 | * | |
| 88 | * @param expectedEmail | |
| 89 | * all the fields with their expected values | |
| 90 | * @param actualEmails | |
| 91 | * the received email | |
| 92 | * @throws MessagingException | |
| 93 | * when accessing the received email fails | |
| 94 | * @throws IOException | |
| 95 | * when reading the content of the email fails | |
| 96 | */ | |
| 97 | public static void assertEquals(ExpectedMultiPartEmail expectedEmail, Message[] actualEmails) throws MessagingException, IOException { | |
| 98 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertEquals → NO_COVERAGE |
assertEquals(new ExpectedMultiPartEmail[] { expectedEmail }, actualEmails); |
| 99 | } | |
| 100 | ||
| 101 | /** | |
| 102 | * Assert that each received email content respects the expected one. It | |
| 103 | * ensures that the number of received emails equals to the expected number. | |
| 104 | * Then for each email it calls | |
| 105 | * {@link #assertEquals(ExpectedMultiPartEmail, Message)} . | |
| 106 | * | |
| 107 | * @param expectedEmails | |
| 108 | * the list of expected emails | |
| 109 | * @param actualEmails | |
| 110 | * the received emails | |
| 111 | * @throws MessagingException | |
| 112 | * when accessing the received email fails | |
| 113 | * @throws IOException | |
| 114 | * when reading the content of the email fails | |
| 115 | */ | |
| 116 | public static void assertEquals(ExpectedMultiPartEmail[] expectedEmails, Message[] actualEmails) throws MessagingException, IOException { | |
| 117 |
1
1. assertEquals : removed call to org/junit/Assert::assertEquals → NO_COVERAGE |
Assert.assertEquals("should have " + expectedEmails.length + " email", expectedEmails.length, actualEmails.length); |
| 118 |
2
1. assertEquals : changed conditional boundary → NO_COVERAGE 2. assertEquals : negated conditional → NO_COVERAGE |
for (int i = 0; i < expectedEmails.length; i++) { |
| 119 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertEquals → NO_COVERAGE |
assertEquals(expectedEmails[i], actualEmails[i]); |
| 120 | } | |
| 121 | } | |
| 122 | ||
| 123 | /** | |
| 124 | *
 | |
| 125 | * Shortcut to simplify unit testing with GreenMail. See | |
| 126 | * {@link #assertEquals(ExpectedEmail[], Message[])}. | |
| 127 | *
 | |
| 128 | * Assert that the fields of the received email are equal to the expected | |
| 129 | * values. The expected email contains only one part (only one content). It | |
| 130 | * will check that: | |
| 131 | *
 | |
| 132 | *
The received headers are respected (see | |
| 133 | * {@link #assertHeaders(ExpectedEmailHeader, Message)})
 | |
| 134 | *
The body equals the expected one (order is important). See | |
| 135 | * {@link #assertBody(String, String, boolean)}
 | |
| 136 | *
The Mime Type equals the expected one (order is important). See | |
| 137 | * {@link #assertMimetype(ExpectedContent, String)}
 | |
| 138 | *
 | |
| 139 | *
 | |
| 140 | * The checking of the body is done strictly (totally equal). | |
| 141 | *
 | |
| 142 | * | |
| 143 | * | |
| 144 | * @param expectedEmail | |
| 145 | * all the fields with their expected values | |
| 146 | * @param actualEmails | |
| 147 | * the received emails | |
| 148 | * @throws MessagingException | |
| 149 | * when accessing the received email fails | |
| 150 | */ | |
| 151 | public static void assertEquals(ExpectedEmail expectedEmail, Message[] actualEmails) throws MessagingException { | |
| 152 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertEquals → NO_COVERAGE |
assertEquals(new ExpectedEmail[] { expectedEmail }, actualEmails); |
| 153 | } | |
| 154 | ||
| 155 | /** | |
| 156 | * Assert that each received email content respects the expected one. It | |
| 157 | * ensures that the number of received emails equals to the expected number. | |
| 158 | * Then for each email it calls | |
| 159 | * {@link #assertEquals(ExpectedEmail, Message)} . | |
| 160 | * | |
| 161 | * @param expectedEmail | |
| 162 | * the expected email | |
| 163 | * @param actualEmails | |
| 164 | * the received emails | |
| 165 | * @throws MessagingException | |
| 166 | * when accessing the received email fails | |
| 167 | */ | |
| 168 | public static void assertEquals(ExpectedEmail[] expectedEmail, Message[] actualEmails) throws MessagingException { | |
| 169 |
1
1. assertEquals : removed call to org/junit/Assert::assertEquals → NO_COVERAGE |
Assert.assertEquals("should have " + expectedEmail.length + " email", expectedEmail.length, actualEmails.length); |
| 170 |
2
1. assertEquals : changed conditional boundary → NO_COVERAGE 2. assertEquals : negated conditional → NO_COVERAGE |
for (int i = 0; i < expectedEmail.length; i++) { |
| 171 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertEquals → NO_COVERAGE |
assertEquals(expectedEmail[i], actualEmails[i]); |
| 172 | } | |
| 173 | } | |
| 174 | ||
| 175 | /** | |
| 176 | * Assert that the fields of the received email are equal to the expected | |
| 177 | * values. The expected email contains only one part (only one content). It | |
| 178 | * will check that: | |
| 179 | *
 | |
| 180 | *
The received headers are respected (see | |
| 181 | * {@link #assertHeaders(ExpectedEmailHeader, Message)})
 | |
| 182 | *
The body equals the expected one (order is important). See | |
| 183 | * {@link #assertBody(String, String, boolean)}
 | |
| 184 | *
The Mime Type equals the expected one (order is important). See | |
| 185 | * {@link #assertMimetype(ExpectedContent, String)}
 | |
| 186 | *
 | |
| 187 | *
 | |
| 188 | * The checking of the body is done strictly (totally equal). | |
| 189 | *
 | |
| 190 | * | |
| 191 | * @param expectedEmail | |
| 192 | * all the fields with their expected values | |
| 193 | * @param actualEmail | |
| 194 | * the received email | |
| 195 | * @throws MessagingException | |
| 196 | * when accessing the received email fails | |
| 197 | */ | |
| 198 | public static void assertEquals(ExpectedEmail expectedEmail, Message actualEmail) throws MessagingException { | |
| 199 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertEquals → NO_COVERAGE |
assertEquals(expectedEmail, actualEmail, true); |
| 200 | } | |
| 201 | ||
| 202 | /** | |
| 203 | * Assert that the fields of the received email are equal to the expected | |
| 204 | * values. The expected email contains several parts (several contents). The | |
| 205 | * received email should also have the equivalent parts. It will check that: | |
| 206 | *
 | |
| 207 | *
The received headers are respected (see | |
| 208 | * {@link #assertHeaders(ExpectedEmailHeader, Message)})
 | |
| 209 | *
The received message is a {@link Multipart} email
 | |
| 210 | *
The number of parts are equal
 | |
| 211 | *
Each received part body equals the expected one (order is important). | |
| 212 | * See {@link #assertBody(String, String, boolean)}
 | |
| 213 | *
Each received part Mime Type equals the expected one (order is | |
| 214 | * important). See {@link #assertMimetype(ExpectedContent, String)}
 | |
| 215 | *
 | |
| 216 | *
 | |
| 217 | * The checking of the body ignores the new line characters. | |
| 218 | *
 | |
| 219 | * | |
| 220 | * @param expectedEmail | |
| 221 | * all the fields with their expected values | |
| 222 | * @param actualEmail | |
| 223 | * the received email | |
| 224 | * @throws MessagingException | |
| 225 | * when accessing the received email fails | |
| 226 | * @throws IOException | |
| 227 | * when reading the content of the email fails | |
| 228 | */ | |
| 229 | public static void assertSimilar(ExpectedMultiPartEmail expectedEmail, Message actualEmail) throws MessagingException, IOException { | |
| 230 |
1
1. assertSimilar : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertEquals → NO_COVERAGE |
assertEquals(expectedEmail, actualEmail, false); |
| 231 | } | |
| 232 | ||
| 233 | /** | |
| 234 | *
 | |
| 235 | * Shortcut to simplify unit testing with GreenMail. See | |
| 236 | * {@link #assertSimilar(ExpectedMultiPartEmail[], Message[])}. | |
| 237 | *
 | |
| 238 | * Assert that the fields of the received email are equal to the expected | |
| 239 | * values. The expected email contains several parts (several contents). The | |
| 240 | * received email should also have the equivalent parts. It will check that: | |
| 241 | *
 | |
| 242 | *
The received headers are respected (see | |
| 243 | * {@link #assertHeaders(ExpectedEmailHeader, Message)})
 | |
| 244 | *
The received message is a {@link Multipart} email
 | |
| 245 | *
The number of parts are equal
 | |
| 246 | *
Each received part body equals the expected one (order is important). | |
| 247 | * See {@link #assertBody(String, String, boolean)}
 | |
| 248 | *
Each received part Mime Type equals the expected one (order is | |
| 249 | * important). See {@link #assertMimetype(ExpectedContent, String)}
 | |
| 250 | *
 | |
| 251 | *
 | |
| 252 | * The checking of the body ignores the new line characters. | |
| 253 | *
 | |
| 254 | * | |
| 255 | * @param expectedEmail | |
| 256 | * all the fields with their expected values | |
| 257 | * @param actualEmails | |
| 258 | * the received email | |
| 259 | * @throws MessagingException | |
| 260 | * when accessing the received email fails | |
| 261 | * @throws IOException | |
| 262 | * when reading the content of the email fails | |
| 263 | */ | |
| 264 | public static void assertSimilar(ExpectedMultiPartEmail expectedEmail, Message[] actualEmails) throws MessagingException, IOException { | |
| 265 |
1
1. assertSimilar : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertSimilar → NO_COVERAGE |
assertSimilar(new ExpectedMultiPartEmail[] { expectedEmail }, actualEmails); |
| 266 | } | |
| 267 | ||
| 268 | /** | |
| 269 | * Assert that each received email content respects the expected one. It | |
| 270 | * ensures that the number of received emails equals to the expected number. | |
| 271 | * Then for each email it calls | |
| 272 | * {@link #assertSimilar(ExpectedMultiPartEmail, Message)} . | |
| 273 | * | |
| 274 | * @param expectedEmails | |
| 275 | * the list of expected emails | |
| 276 | * @param actualEmails | |
| 277 | * the received emails | |
| 278 | * @throws MessagingException | |
| 279 | * when accessing the received email fails | |
| 280 | * @throws IOException | |
| 281 | * when reading the content of the email fails | |
| 282 | */ | |
| 283 | public static void assertSimilar(ExpectedMultiPartEmail[] expectedEmails, Message[] actualEmails) throws MessagingException, IOException { | |
| 284 |
1
1. assertSimilar : removed call to org/junit/Assert::assertEquals → NO_COVERAGE |
Assert.assertEquals("should have " + expectedEmails.length + " email", expectedEmails.length, actualEmails.length); |
| 285 |
2
1. assertSimilar : changed conditional boundary → NO_COVERAGE 2. assertSimilar : negated conditional → NO_COVERAGE |
for (int i = 0; i < expectedEmails.length; i++) { |
| 286 |
1
1. assertSimilar : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertSimilar → NO_COVERAGE |
assertSimilar(expectedEmails[i], actualEmails[i]); |
| 287 | } | |
| 288 | } | |
| 289 | ||
| 290 | /** | |
| 291 | *
 | |
| 292 | * Shortcut to simplify unit testing with GreenMail. See | |
| 293 | * {@link #assertSimilar(ExpectedEmail[], Message[])}. | |
| 294 | *
 | |
| 295 | * Assert that the fields of the received email are equal to the expected | |
| 296 | * values. The expected email contains only one part (only one content). It | |
| 297 | * will check that: | |
| 298 | *
 | |
| 299 | *
The received headers are respected (see | |
| 300 | * {@link #assertHeaders(ExpectedEmailHeader, Message)})
 | |
| 301 | *
The body equals the expected one (order is important). See | |
| 302 | * {@link #assertBody(String, String, boolean)}
 | |
| 303 | *
The Mime Type equals the expected one (order is important). See | |
| 304 | * {@link #assertMimetype(ExpectedContent, String)}
 | |
| 305 | *
 | |
| 306 | *
 | |
| 307 | * The checking of the body ignores the new line characters. | |
| 308 | *
 | |
| 309 | * | |
| 310 | * | |
| 311 | * @param expectedEmail | |
| 312 | * all the fields with their expected values | |
| 313 | * @param actualEmails | |
| 314 | * the received emails | |
| 315 | * @throws MessagingException | |
| 316 | * when accessing the received email fails | |
| 317 | */ | |
| 318 | public static void assertSimilar(ExpectedEmail expectedEmail, Message[] actualEmails) throws MessagingException { | |
| 319 |
1
1. assertSimilar : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertSimilar → NO_COVERAGE |
assertSimilar(new ExpectedEmail[] { expectedEmail }, actualEmails); |
| 320 | } | |
| 321 | ||
| 322 | /** | |
| 323 | * Assert that each received email content respects the expected one. It | |
| 324 | * ensures that the number of received emails equals to the expected number. | |
| 325 | * Then for each email it calls | |
| 326 | * {@link #assertSimilar(ExpectedEmail, Message)} . | |
| 327 | * | |
| 328 | * @param expectedEmail | |
| 329 | * the expected email | |
| 330 | * @param actualEmails | |
| 331 | * the received emails | |
| 332 | * @throws MessagingException | |
| 333 | * when accessing the received email fails | |
| 334 | */ | |
| 335 | public static void assertSimilar(ExpectedEmail[] expectedEmail, Message[] actualEmails) throws MessagingException { | |
| 336 |
1
1. assertSimilar : removed call to org/junit/Assert::assertEquals → NO_COVERAGE |
Assert.assertEquals("should have " + expectedEmail.length + " email", expectedEmail.length, actualEmails.length); |
| 337 |
2
1. assertSimilar : changed conditional boundary → NO_COVERAGE 2. assertSimilar : negated conditional → NO_COVERAGE |
for (int i = 0; i < expectedEmail.length; i++) { |
| 338 |
1
1. assertSimilar : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertSimilar → NO_COVERAGE |
assertSimilar(expectedEmail[i], actualEmails[i]); |
| 339 | } | |
| 340 | } | |
| 341 | ||
| 342 | /** | |
| 343 | * Assert that the fields of the received email are equal to the expected | |
| 344 | * values. The expected email contains only one part (only one content). It | |
| 345 | * will check that: | |
| 346 | *
 | |
| 347 | *
The received headers are respected (see | |
| 348 | * {@link #assertHeaders(ExpectedEmailHeader, Message)})
 | |
| 349 | *
The body equals the expected one (order is important). See | |
| 350 | * {@link #assertBody(String, String, boolean)}
 | |
| 351 | *
The Mime Type equals the expected one (order is important). See | |
| 352 | * {@link #assertMimetype(ExpectedContent, String)}
 | |
| 353 | *
 | |
| 354 | *
 | |
| 355 | * The checking of the body ignores the new line characters. | |
| 356 | *
 | |
| 357 | * | |
| 358 | * @param expectedEmail | |
| 359 | * all the fields with their expected values | |
| 360 | * @param actualEmail | |
| 361 | * the received email | |
| 362 | * @throws MessagingException | |
| 363 | * when accessing the received email fails | |
| 364 | */ | |
| 365 | public static void assertSimilar(ExpectedEmail expectedEmail, Message actualEmail) throws MessagingException { | |
| 366 |
1
1. assertSimilar : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertEquals → NO_COVERAGE |
assertEquals(expectedEmail, actualEmail, false); |
| 367 | } | |
| 368 | ||
| 369 | /** | |
| 370 | * Assert that the fields of the received email are equal to the expected | |
| 371 | * values. The expected email contains several parts (several contents). The | |
| 372 | * received email should also have the equivalent parts. It will check that: | |
| 373 | *
 | |
| 374 | *
The received headers are respected (see | |
| 375 | * {@link #assertHeaders(ExpectedEmailHeader, Message)})
 | |
| 376 | *
The received message is a {@link Multipart} email
 | |
| 377 | *
The number of parts are equal
 | |
| 378 | *
Each received part body equals the expected one (order is important). | |
| 379 | * See {@link #assertBody(String, String, boolean)}
 | |
| 380 | *
Each received part Mime Type equals the expected one (order is | |
| 381 | * important). See {@link #assertMimetype(ExpectedContent, String)}
 | |
| 382 | *
 | |
| 383 | *
 | |
| 384 | * The checking of the body may be done either strictly (totally equal) or | |
| 385 | * not (new line characters are ignored). | |
| 386 | *
 | |
| 387 | * | |
| 388 | * @param expectedEmail | |
| 389 | * all the fields with their expected values | |
| 390 | * @param actualEmail | |
| 391 | * the received email | |
| 392 | * @param strict | |
| 393 | * true for strict checking (totally equals) or false to ignore | |
| 394 | * new line characters in body contents | |
| 395 | * @throws MessagingException | |
| 396 | * when accessing the received email fails | |
| 397 | * @throws IOException | |
| 398 | * when reading the content of the email fails | |
| 399 | */ | |
| 400 | public static void assertEquals(ExpectedMultiPartEmail expectedEmail, Message actualEmail, boolean strict) throws MessagingException, IOException { | |
| 401 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertHeaders → NO_COVERAGE |
assertHeaders(expectedEmail, actualEmail); |
| 402 | Object content = actualEmail.getContent(); | |
| 403 |
1
1. assertEquals : removed call to org/junit/Assert::assertTrue → NO_COVERAGE |
Assert.assertTrue("should be multipart message", content instanceof Multipart); |
| 404 | List<Part> bodyParts = getBodyParts(actualEmail); | |
| 405 |
1
1. assertEquals : removed call to org/junit/Assert::assertEquals → NO_COVERAGE |
Assert.assertEquals("should have " + expectedEmail.getExpectedContents().length + " parts", expectedEmail.getExpectedContents().length, bodyParts.size()); |
| 406 |
3
1. assertEquals : changed conditional boundary → NO_COVERAGE 2. assertEquals : Changed increment from 1 to -1 → NO_COVERAGE 3. assertEquals : negated conditional → NO_COVERAGE |
for (int i = 0; i < expectedEmail.getExpectedContents().length; i++) { |
| 407 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertBody → NO_COVERAGE |
assertBody(expectedEmail.getExpectedContents()[i].getBody(), bodyParts.get(i).getContent().toString(), strict); |
| 408 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertMimetype → NO_COVERAGE |
assertMimetype(expectedEmail.getExpectedContents()[i], bodyParts.get(i).getContentType()); |
| 409 | } | |
| 410 | } | |
| 411 | ||
| 412 | /** | |
| 413 | * Assert that the fields of the received email are equal to the expected | |
| 414 | * values. The expected email contains only one part (only one content). It | |
| 415 | * will check that: | |
| 416 | *
 | |
| 417 | *
The received headers are respected (see | |
| 418 | * {@link #assertHeaders(ExpectedEmailHeader, Message)})
 | |
| 419 | *
The body equals the expected one (order is important). See | |
| 420 | * {@link #assertBody(String, String, boolean)}
 | |
| 421 | *
The Mime Type equals the expected one (order is important). See | |
| 422 | * {@link #assertMimetype(ExpectedContent, String)}
 | |
| 423 | *
 | |
| 424 | *
 | |
| 425 | * The checking of the body may be done either strictly (totally equal) or | |
| 426 | * not (new line characters are ignored). | |
| 427 | *
 | |
| 428 | * | |
| 429 | * @param expectedEmail | |
| 430 | * all the fields with their expected values | |
| 431 | * @param actualEmail | |
| 432 | * the received email | |
| 433 | * @param strict | |
| 434 | * true for strict checking (totally equals) or false to ignore | |
| 435 | * new line characters in body contents | |
| 436 | * @throws MessagingException | |
| 437 | * when accessing the received email fails | |
| 438 | */ | |
| 439 | public static void assertEquals(ExpectedEmail expectedEmail, Message actualEmail, boolean strict) throws MessagingException { | |
| 440 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertHeaders → NO_COVERAGE |
assertHeaders(expectedEmail, actualEmail); |
| 441 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertBody → NO_COVERAGE |
assertBody(expectedEmail.getExpectedContent().getBody(), getBody(actualEmail), strict); |
| 442 |
1
1. assertEquals : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertMimetype → NO_COVERAGE |
assertMimetype(expectedEmail.getExpectedContent(), getBodyMimetype(actualEmail)); |
| 443 | } | |
| 444 | ||
| 445 | /** | |
| 446 | * Checks that the received Mime Type for the message is like the expected | |
| 447 | * Mime Type. The expected Mime Type is a regular expression. | |
| 448 | * | |
| 449 | * @param expectedContent | |
| 450 | * the expected email content that contains the expected Mime | |
| 451 | * Type as regular expression | |
| 452 | * @param actualEmail | |
| 453 | * the received email to check | |
| 454 | * @throws MessagingException | |
| 455 | * when accessing the received email fails | |
| 456 | */ | |
| 457 | public static void assertMimetype(ExpectedContent expectedContent, Message actualEmail) throws MessagingException { | |
| 458 |
1
1. assertMimetype : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertMimetype → NO_COVERAGE |
assertMimetype(expectedContent, actualEmail.getContentType()); |
| 459 | } | |
| 460 | ||
| 461 | /** | |
| 462 | * Checks that the received Mime Type for the message is like the expected | |
| 463 | * Mime Type. The expected Mime Type is a regular expression. | |
| 464 | * | |
| 465 | * @param expectedContent | |
| 466 | * the expected email content that contains the expected Mime | |
| 467 | * Type as regular expression | |
| 468 | * @param contentType | |
| 469 | * the received email Mime Type | |
| 470 | * @throws MessagingException | |
| 471 | * when accessing the received email fails | |
| 472 | */ | |
| 473 | public static void assertMimetype(ExpectedContent expectedContent, String contentType) throws MessagingException { | |
| 474 |
1
1. assertMimetype : removed call to org/junit/Assert::assertTrue → NO_COVERAGE |
Assert.assertTrue("mimetype should be " + expectedContent.getMimetype() + " instead of " + contentType, expectedContent.getMimetype().matcher(contentType).matches()); |
| 475 | } | |
| 476 | ||
| 477 | /** | |
| 478 | * Checks if the received body equals the expected body. It handles HTML | |
| 479 | * content and pure text content. | |
| 480 | *
 | |
| 481 | * For text, the check can be done either strictly (totally equal) or not | |
| 482 | * (ignore new lines). | |
| 483 | *
 | |
| 484 | *
 | |
| 485 | * For HTML, the string content is parsed and DOM trees are compared. The | |
| 486 | * comparison can be done either strictly (DOM trees are totally equals, | |
| 487 | * attributes are in the same order) or not (attributes can be in any | |
| 488 | * order). | |
| 489 | *
 | |
| 490 | * | |
| 491 | * @param expectedBody | |
| 492 | * the expected content as string | |
| 493 | * @param actualBody | |
| 494 | * the received content as string | |
| 495 | * @param strict | |
| 496 | * true for strict checking (totally equals) or false to ignore | |
| 497 | * new line characters | |
| 498 | */ | |
| 499 | public static void assertBody(String expectedBody, String actualBody, boolean strict) { | |
| 500 |
1
1. assertBody : negated conditional → NO_COVERAGE |
if (isHtml(expectedBody)) { |
| 501 |
1
1. assertBody : negated conditional → NO_COVERAGE |
if (strict) { |
| 502 |
1
1. assertBody : removed call to fr/sii/ogham/testing/helper/html/AssertHtml::assertIdentical → NO_COVERAGE |
AssertHtml.assertIdentical(expectedBody, actualBody); |
| 503 | } else { | |
| 504 |
1
1. assertBody : removed call to fr/sii/ogham/testing/helper/html/AssertHtml::assertSimilar → NO_COVERAGE |
AssertHtml.assertSimilar(expectedBody, actualBody); |
| 505 | } | |
| 506 | } else { | |
| 507 |
3
1. assertBody : negated conditional → NO_COVERAGE 2. assertBody : negated conditional → NO_COVERAGE 3. assertBody : negated conditional → NO_COVERAGE |
if(strict ? !expectedBody.equals(actualBody) : !sanitize(expectedBody).equals(sanitize(actualBody))) { |
| 508 | throw new ComparisonFailure("body should be '" + expectedBody + "'", expectedBody, actualBody); | |
| 509 | } | |
| 510 | } | |
| 511 | } | |
| 512 | ||
| 513 | /** | |
| 514 | * Checks if the received headers corresponds to the expected header values. | |
| 515 | * It checks if: | |
| 516 | *
 | |
| 517 | *
The received subject equals the expected subject
 | |
| 518 | *
The email sender address equals the expected sender address
 | |
| 519 | *
The total number of recipients equals the total number of expected | |
| 520 | * recipients
 | |
| 521 | *
The number of "to" recipients equals the number of expected "to" | |
| 522 | * recipients
 | |
| 523 | *
The number of "cc" recipients equals the number of expected "cc" | |
| 524 | * recipients
 | |
| 525 | *
The number of "bcc" recipients equals the number of expected "bcc" | |
| 526 | * recipients
 | |
| 527 | *
Each "to" recipient equals the expected "to" recipient value
 | |
| 528 | *
Each "cc" recipient equals the expected "cc" recipient value
 | |
| 529 | *
Each "bcc" recipient equals the expected "bcc" recipient value
 | |
| 530 | *
 | |
| 531 | * | |
| 532 | * @param expectedEmail | |
| 533 | * the expected header values | |
| 534 | * @param actualEmail | |
| 535 | * the received header values | |
| 536 | * @throws MessagingException | |
| 537 | * when accessing the received email fails | |
| 538 | */ | |
| 539 | public static void assertHeaders(ExpectedEmailHeader expectedEmail, Message actualEmail) throws MessagingException { | |
| 540 |
1
1. assertHeaders : removed call to org/junit/Assert::assertEquals → NO_COVERAGE |
Assert.assertEquals("subject should be '" + expectedEmail.getSubject() + "'", expectedEmail.getSubject(), actualEmail.getSubject()); |
| 541 |
1
1. assertHeaders : removed call to org/junit/Assert::assertEquals → NO_COVERAGE |
Assert.assertEquals("should have only one from", 1, actualEmail.getFrom().length); |
| 542 |
1
1. assertHeaders : removed call to org/junit/Assert::assertEquals → NO_COVERAGE |
Assert.assertEquals("from should be '" + expectedEmail.getFrom() + "'", expectedEmail.getFrom(), actualEmail.getFrom()[0].toString()); |
| 543 |
2
1. assertHeaders : Replaced integer addition with subtraction → NO_COVERAGE 2. assertHeaders : Replaced integer addition with subtraction → NO_COVERAGE |
int recipients = expectedEmail.getTo().size() + expectedEmail.getBcc().size() + expectedEmail.getCc().size(); |
| 544 |
1
1. assertHeaders : removed call to org/junit/Assert::assertEquals → NO_COVERAGE |
Assert.assertEquals("should have only " + recipients + " recipients", recipients, actualEmail.getAllRecipients().length); |
| 545 |
1
1. assertHeaders : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertRecipients → NO_COVERAGE |
assertRecipients(expectedEmail.getTo(), actualEmail, RecipientType.TO); |
| 546 |
1
1. assertHeaders : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertRecipients → NO_COVERAGE |
assertRecipients(expectedEmail.getCc(), actualEmail, RecipientType.CC); |
| 547 |
1
1. assertHeaders : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::assertRecipients → NO_COVERAGE |
assertRecipients(expectedEmail.getBcc(), actualEmail, RecipientType.BCC); |
| 548 | } | |
| 549 | ||
| 550 | /** | |
| 551 | * Checks if the received headers corresponds to the expected header values. | |
| 552 | * It checks if: | |
| 553 | *
 | |
| 554 | *
The number of recipients of the provided type equals the number of | |
| 555 | * expected recipients of the provided type
 | |
| 556 | *
Each recipient of the provided type equals the expected recipient | |
| 557 | * value of the provided type
 | |
| 558 | *
 | |
| 559 | * | |
| 560 | * @param expectedRecipients | |
| 561 | * the list of recipient string values | |
| 562 | * @param actualEmail | |
| 563 | * the received header values | |
| 564 | * @param recipientType | |
| 565 | * the type of the recipient to compare | |
| 566 | * @throws MessagingException | |
| 567 | * when accessing the received email fails | |
| 568 | */ | |
| 569 | public static void assertRecipients(List<String> expectedRecipients, Message actualEmail, RecipientType recipientType) throws MessagingException { | |
| 570 | Address[] actualRecipients = actualEmail.getRecipients(recipientType); | |
| 571 |
1
1. assertRecipients : negated conditional → NO_COVERAGE |
if (expectedRecipients.isEmpty()) { |
| 572 |
3
1. assertRecipients : negated conditional → NO_COVERAGE 2. assertRecipients : negated conditional → NO_COVERAGE 3. assertRecipients : removed call to org/junit/Assert::assertTrue → NO_COVERAGE |
Assert.assertTrue("should have no recipients " + recipientType, actualRecipients == null || actualRecipients.length == 0); |
| 573 | } else { | |
| 574 |
1
1. assertRecipients : removed call to org/junit/Assert::assertEquals → NO_COVERAGE |
Assert.assertEquals("should have only " + expectedRecipients.size() + " " + recipientType, expectedRecipients.size(), actualRecipients.length); |
| 575 |
2
1. assertRecipients : changed conditional boundary → NO_COVERAGE 2. assertRecipients : negated conditional → NO_COVERAGE |
for (int i = 0; i < expectedRecipients.size(); i++) { |
| 576 |
1
1. assertRecipients : removed call to org/junit/Assert::assertEquals → NO_COVERAGE |
Assert.assertEquals(recipientType + "[" + i + "] should be '" + expectedRecipients.get(i) + "'", expectedRecipients.get(i), actualRecipients[i].toString()); |
| 577 | } | |
| 578 | } | |
| 579 | } | |
| 580 | ||
| 581 | /** | |
| 582 | * Remove new lines from the string. | |
| 583 | * | |
| 584 | * @param str | |
| 585 | * the string to sanitize | |
| 586 | * @return the sanitized string | |
| 587 | */ | |
| 588 | private static String sanitize(String str) { | |
| 589 |
1
1. sanitize : replaced return value with "" for fr/sii/ogham/testing/helper/email/AssertEmail::sanitize → NO_COVERAGE |
return str.replaceAll("\r|\n", ""); |
| 590 | } | |
| 591 | ||
| 592 | private static Part getBodyPart(Part actualEmail) throws MessagingException { | |
| 593 | List<Part> bodyParts = getBodyParts(actualEmail); | |
| 594 |
1
1. getBodyPart : negated conditional → NO_COVERAGE |
if(bodyParts.isEmpty()) { |
| 595 | throw new IllegalStateException("Expected at least one body part but none found"); | |
| 596 | } | |
| 597 |
1
1. getBodyPart : replaced return value with null for fr/sii/ogham/testing/helper/email/AssertEmail::getBodyPart → NO_COVERAGE |
return bodyParts.get(0); |
| 598 | } | |
| 599 | ||
| 600 | private static List<Part> getBodyParts(Part actualEmail) throws MessagingException { | |
| 601 | List<Part> founds = new ArrayList<>(); | |
| 602 |
1
1. getBodyParts : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::getBodyParts → NO_COVERAGE |
getBodyParts(actualEmail, founds); |
| 603 |
1
1. getBodyParts : replaced return value with Collections.emptyList for fr/sii/ogham/testing/helper/email/AssertEmail::getBodyParts → NO_COVERAGE |
return founds; |
| 604 | } | |
| 605 | | |
| 606 | private static void getBodyParts(Part actualEmail, List<Part> founds) throws MessagingException { | |
| 607 | try { | |
| 608 | Object content = actualEmail.getContent(); | |
| 609 |
1
1. getBodyParts : negated conditional → NO_COVERAGE |
if (content instanceof Multipart) { |
| 610 | Multipart mp = (Multipart) content; | |
| 611 |
2
1. getBodyParts : changed conditional boundary → NO_COVERAGE 2. getBodyParts : negated conditional → NO_COVERAGE |
for(int i=0 ; i<mp.getCount() ; i++) { |
| 612 |
1
1. getBodyParts : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::addPart → NO_COVERAGE |
addPart(founds, mp, i); |
| 613 | } | |
| 614 | } | |
| 615 | } catch (IOException e) { | |
| 616 | throw new MessagingException("Failed to access content of the mail", e); | |
| 617 | } | |
| 618 | } | |
| 619 | ||
| 620 | private static void addPart(List<Part> founds, Multipart mp, int i) throws MessagingException { | |
| 621 | BodyPart part = mp.getBodyPart(i); | |
| 622 |
1
1. addPart : negated conditional → NO_COVERAGE |
if(part.getContentType().startsWith("multipart/")) { |
| 623 |
1
1. addPart : removed call to fr/sii/ogham/testing/helper/email/AssertEmail::getBodyParts → NO_COVERAGE |
getBodyParts(part, founds); |
| 624 |
1
1. addPart : negated conditional → NO_COVERAGE |
} else if(TEXT_OR_HTML_MIMETYPES.matcher(part.getContentType()).matches()){ |
| 625 | founds.add(part); | |
| 626 | } | |
| 627 | } | |
| 628 | ||
| 629 | private static String getBody(Part actualEmail) throws MessagingException { | |
| 630 | try { | |
| 631 | Object content = getBodyPart(actualEmail).getContent(); | |
| 632 |
1
1. getBody : negated conditional → NO_COVERAGE |
if(content instanceof String) { |
| 633 |
1
1. getBody : replaced return value with "" for fr/sii/ogham/testing/helper/email/AssertEmail::getBody → NO_COVERAGE |
return (String) content; |
| 634 |
1
1. getBody : negated conditional → NO_COVERAGE |
} else if(content instanceof InputStream) { |
| 635 |
1
1. getBody : replaced return value with "" for fr/sii/ogham/testing/helper/email/AssertEmail::getBody → NO_COVERAGE |
return IOUtils.toString((InputStream) content, Charset.defaultCharset()); |
| 636 | } else { | |
| 637 |
1
1. getBody : replaced return value with "" for fr/sii/ogham/testing/helper/email/AssertEmail::getBody → NO_COVERAGE |
return content.toString(); |
| 638 | } | |
| 639 | } catch (IOException e) { | |
| 640 | throw new MessagingException("Failed to access content of the mail", e); | |
| 641 | } | |
| 642 | } | |
| 643 | ||
| 644 | private static String getBodyMimetype(Part actualEmail) throws MessagingException { | |
| 645 |
1
1. getBodyMimetype : replaced return value with "" for fr/sii/ogham/testing/helper/email/AssertEmail::getBodyMimetype → NO_COVERAGE |
return getBodyPart(actualEmail).getContentType(); |
| 646 | } | |
| 647 | | |
| 648 | private static boolean isHtml(String expectedBody) { | |
| 649 |
2
1. isHtml : replaced boolean return with false for fr/sii/ogham/testing/helper/email/AssertEmail::isHtml → NO_COVERAGE 2. isHtml : replaced boolean return with true for fr/sii/ogham/testing/helper/email/AssertEmail::isHtml → NO_COVERAGE |
return HTML_PATTERN.matcher(expectedBody).find(); |
| 650 | } | |
| 651 | | |
| 652 | private AssertEmail() { | |
| 653 | super(); | |
| 654 | } | |
| 655 | } | |
Mutations | ||
| 63 |
1.1 |
|
| 98 |
1.1 |
|
| 117 |
1.1 |
|
| 118 |
1.1 2.2 |
|
| 119 |
1.1 |
|
| 152 |
1.1 |
|
| 169 |
1.1 |
|
| 170 |
1.1 2.2 |
|
| 171 |
1.1 |
|
| 199 |
1.1 |
|
| 230 |
1.1 |
|
| 265 |
1.1 |
|
| 284 |
1.1 |
|
| 285 |
1.1 2.2 |
|
| 286 |
1.1 |
|
| 319 |
1.1 |
|
| 336 |
1.1 |
|
| 337 |
1.1 2.2 |
|
| 338 |
1.1 |
|
| 366 |
1.1 |
|
| 401 |
1.1 |
|
| 403 |
1.1 |
|
| 405 |
1.1 |
|
| 406 |
1.1 2.2 3.3 |
|
| 407 |
1.1 |
|
| 408 |
1.1 |
|
| 440 |
1.1 |
|
| 441 |
1.1 |
|
| 442 |
1.1 |
|
| 458 |
1.1 |
|
| 474 |
1.1 |
|
| 500 |
1.1 |
|
| 501 |
1.1 |
|
| 502 |
1.1 |
|
| 504 |
1.1 |
|
| 507 |
1.1 2.2 3.3 |
|
| 540 |
1.1 |
|
| 541 |
1.1 |
|
| 542 |
1.1 |
|
| 543 |
1.1 2.2 |
|
| 544 |
1.1 |
|
| 545 |
1.1 |
|
| 546 |
1.1 |
|
| 547 |
1.1 |
|
| 571 |
1.1 |
|
| 572 |
1.1 2.2 3.3 |
|
| 574 |
1.1 |
|
| 575 |
1.1 2.2 |
|
| 576 |
1.1 |
|
| 589 |
1.1 |
|
| 594 |
1.1 |
|
| 597 |
1.1 |
|
| 602 |
1.1 |
|
| 603 |
1.1 |
|
| 609 |
1.1 |
|
| 611 |
1.1 2.2 |
|
| 612 |
1.1 |
|
| 622 |
1.1 |
|
| 623 |
1.1 |
|
| 624 |
1.1 |
|
| 632 |
1.1 |
|
| 633 |
1.1 |
|
| 634 |
1.1 |
|
| 635 |
1.1 |
|
| 637 |
1.1 |
|
| 645 |
1.1 |
|
| 649 |
1.1 2.2 |


This assignment is to be done either individually or in pairs. Do not show your code to any other group and do not look at any other group's code. Do not put your code in a public directory or otherwise make it public. However, you may get help from the mentors, TAs, or the instructor. You are encouraged to use the Submitty Discussion Forum to post problems so that other students can also answer/see the answers.
The goal of this assignment is to write a lambda calculus interpreter in a functional programming language to reduce lambda calculus expressions in a call-by-name (normal order) manner.
You are to use the following grammar for the lambda calculus:
<expression>
::=
<atom>
|
"\" <atom> "."  It must then perform eta reduction until no longer possible.
In the above grammar,
<atom>
is defined as a lower case letter followed by a sequence of zero or more alphanumeric characters, excluding Oz language keywords. A full listing of Oz language keywords can be found on P. 839 Table C.8 of "Concepts, Techniques, and Models of Computer Programming". Your interpreter is to take lambda calculus expressions from a text file (one expression per line) and reduce them sequentially. To enable you to focus on the lambda calculus semantics, a parser is available for both Haskell and Oz, along with supporting code to handle input and output.
Your program must accept two command line arguments. The first argument is the name of a file containing a list of lambda calculus expressions. The second argument is the name of the file you will write your reduced lambda calculus expressions into.
Your parser should write out the reduced expressions to a file, again one per line. If something goes wrong and you cannot reduce an expression, you should write a single new line and then continue with the next lambda calculus expression. Writing more than one line, or writing nothing at all, will interfere with autograding. Do not write anything else, such as debug printouts, test numbers, etc.
You may (and should!) define auxiliary procedures for alpha-renaming, beta-reduction, and eta-conversion. For beta reduction, you may want to write an auxiliary procedure that substitutes all occurrences of a variable in an expression for another expression. Be sure that the replacing expression does not include free variables that would become captured in the substitution. Remember that in call-by-name, the argument to a function is not evaluated before the function is called.
You may choose whatever names you wish when alpha-renaming, as long as they do not violate the definition of <atom>. Your code will be judged correct if we could make your solution match our solution by renaming zero or more of your variable names.
Below are some lambda calculus interpretation test cases:
| Expression | Result | Comment |
|---|---|---|
(\x.\y.(y x) (y w))
|
\z.(z (y w))
|
Avoid capturing the free variable
y in
(y w)
|
(\x.\y.(x y) (y w))
|
(y w)
|
Avoid capturing the free variable
y in
(y w) , and perform eta reduction
|
(\x.x y)
|
y
|
Identity combinator |
\x.(y x)
|
y
|
Eta reduction |
((\y.\x.(y x) \x.(x x)) y)
|
(y y)
|
Application combinator |
(((\b.\t.\e.((b t) e) \x.\y.x) x) y)
|
x
|
If-then-else combinator |
\x.((\x.(y x) \x.(z x)) x)
|
(y z)
|
Eta reductions |
(\y.(\x.\y.(x y) y) (y w))
|
(y w)
|
Alpha renaming, beta reduction and eta reduction all involved |
For your convenience, these have been given in a sample input file, where each line contains one lambda expression.
You should remove any other Oz installations and use Mozart 2. You can download the binaries from the project's GitHub repository.
Note for Windows users: the interactive Oz editor may fail to launch if you install Mozart on a path containing spaces. It may also fail to launch due to problems with your environment (causing Mozart to be unable to find its bundled copy of Emacs). If you are having problems, please post about it on Submitty or come to office hours for help.
A parser is provided. Use this starter code and this provided main file. main.oz receives command line arguments and invokes PA1Helper's RunProgram procedure, which handles reading the input and writing output. You will need to implement the ReduceExp method. The program will write reduced expressions to the output file and print out both the original and reduced expressions to stdout. Only the lines written to the file will be considered when grading.
$ cat sample.lambda (\x.x y) (\x.\y.(x y) (y w)) $ ozc -c parser.oz $ ozc -c PA1Helper.oz $ ozc -c main.oz $ ozengine main.ozf sample.lambda output.lambda $ cat output.lambda y (y w)
Use
this parser to get a list of lambda calculus expressions from an input file. See also the
sample main.hs file (in particular, see the
runProgram
function.) Specifically, type constructors for the
Lexp
datatype have been exported from the module. This datatype is used to represent lambda calculus expressions in Haskell, and the type constructors should be used to pattern match a lambda expression. Your goal is to create a
reducer
function that takes an
Lexp
value as input and returns a
Lexp
value as output.
The provided helper code will both write to stdout and to the output file. The former is inteded to help you during the development process. Only the lines written to the file will matter when the assignment is graded.
Note: Please name your main file 'main.hs'. It should accept two arguments when compiled and executed. The provided main.hs has this functionality provided.
$ cat sample.lambda (\x.x y) (\x.\y.(x y) (y w)) $ runghc main.hs sample.lambda output.lambda $ cat output.lambda y (y w)
If you get an error about Text.Parsec being undefined, run
stack install parsec
(or
cabal install parsec
)
Further Haskell Hints: It may be useful to consider Map and Set, which can be found in the Data.Map and Data.Set modules, respectively. It is also recommended to use Hoogle, a search engine for looking up Haskell documentation.
If you use an unusual library, you will need to contact the course TAs to have them installed on the Submitty server. Otherwise, your solution will not compile.
Grading: The assignment will be graded mostly on correctness, but code clarity / readability will also be a factor. If something is unclear, explain it with comments!
Correctness is judged by testing if your lambda calculus expressions are alpha-equivalent to the expected expressions. Therefore, your choice of names when performing alpha renaming will not affect correctness, as long as your chosen names are valid (i.e. lowercase alphanumeric strings that start with a letter and are not Oz keywords).
Submission Requirements: You will submit your code via Submitty. Include all source files need to run your program, as well as a README file. We will not automatically include any provided code. In the README file, place the names of each group member (up to two). Your README file should also have a list of specific features/bugs in your solution. If you are working with another student, then only one member of the team needs to submit.
Working alone/in pairs: You may work alone, or with one other student. To work alone, simply create a new team on Submitty with only yourself in it. To work with a partner, either invite them to your team, or join their team.


Deploy Postfix Gmail relay with Ansible on Raspberry Pi
Why would we want to do this?🔗
The virtualization servers at work are running VMWare ESXi, with Vcenter Server Applicance (VCSA) as our bridge to using cool, free tools like Packer, and Terraform to automate my interactions with virtual resources.
A downside we discovered is VCSA's lack of support for SMTP that requires auth, which Google requires when you send mail through them.
Postfix can handle the anonymous request from VCSA, and send it out to gmail with provided creds.
How do I get started?🔗
Since we wanted to get an email whenever there as an issue with the virtualization servers, it made sense to hostthis service on its own hardware.
I am going to be hosting this service using a Raspberry Pi 3 model B running Raspbian Stretch, and configuring it from my host using Ansible. This detail is not critical for following this guide. Any Debian-derived OS (like Ubuntu) that Ansible supports will work for hosting.
You just need to make sure SSH is turned on, and that you have the IP address. (The default username/pass on RasPis is pi
/raspberry
)
At minimum, you need the following tools installed on your host:
- Python 3
- Ansible 2.7
Download this helpful role for installing Postfix. At the time of this writing, it was the best public Postfix Ansible role, because its documentation had examples of how to configure the deployment as a gmail relay. Very straight forward.
https://github.com/Oefenweb/ansible-postfix
If you install this role in your Ansible client's role_path
, then you can use the example playbook I slightly modified, (and annotated) from the ansible-postfix README.
Example ansible playbook🔗
---
name: Setup basic raspberry pi host as SMTP relay (Rasbian)
hosts:
mailproxy
vars:
postfix_mynetworks:
# This is the IPv4 localhost loopback subnet
- '<IP_ADDRESS>/8'
# This is the IPv4 mapped IPv6 localhost loopback subnet
- '[::ffff:<IP_ADDRESS>]/104'
# This is the IPv6 localhost loopback address
- '[::1]/128'
# This is the local private network subnet, like the IPv4 address space from your home router
# This addition allows other hosts on the network to send mail through this relay!
- '<IP_ADDRESS>/24'
postfix_smtpd_relay_restrictions:
# This says to permit requests if the client is in the $mynetworks whitelist
# http://www.postfix.org/postconf.5.html#permit_mynetworks
- permit_mynetworks
# This says relay the request if client is authenticated to the smtp server
# http://www.postfix.org/postconf.5.html#permit_sasl_authenticated
- permit_sasl_authenticated
# This says to reject the request unless it knows about the destination (the domain)
# http://www.postfix.org/postconf.5.html#reject_unauth_destination
- reject_unauth_destination
## Lastly, I believe the order of these restrictions matter, so this last one must catch the rest of the garbage requests
postfix_relayhost: smtp.gmail.com
postfix_smtp_tls_cafile: /etc/ssl/certs/ca-certificates.crt
postfix_relaytls: true
postfix_sasl_user<EMAIL_ADDRESS>postfix_sasl_password: 'apppasswordgeneratedgarbage'
roles:
ansible-postfix
Some additional notes🔗
- To configure vCenter, I followed this guide. It might be helpful to note that I only found these instructions to work with the Flash-based client, not the HTML5-based client. But it would be really great if the settings could be configured over the command line with VMWare's vSphere CLI tool, govc
- Without the
postfix_mynetworks
addition of my local network, I was unable to successfully see email alerts from VCSA being sent from Postfix - This also differs from the Oefenweb/ansible-postfix example, in that I am not setting any
postfix_aliases
, since it was my experience that it didn't ever work. Email was always from whoever was configured aspostfix_sasl_user
Test the configuration🔗
Here is how to send a test email, from the Raspberry Pi, using mail
pi@raspberrypi:~ $ echo "Hello world, it's ya boi, RaspberryPi" | mail -s "[SMTP proxy] Hello World" your.email@domain.com


i2b2 (Informatics for Integrating Biology and the Bedside) is an NIH-funded National Center for Biomedical Computing. The i2b2 Center is developing a scalable informatics framework that will bridge clinical research data and the vast data banks arising from basic science research in order to better understand the genetic bases of complex diseases. This knowledge will facilitate the design of targeted therapies for individual patients with diseases having genetic origins. The i2b2 web client is a web-based interface to the i2b2 Hive, which is a collection of modular i2b2 Cells that provide functionality such as project management, ontology management, access to clinical data repositories, workflow and data analysis.
Browser Requirements
The i2b2 web client has been tested on Internet Explorer 6 and 7, Firefox 2 and 3, and Safari 3. JavaScript must be enabled.
Implemented Cells
The i2b2 web client brings much of the functionality of the i2b2 desktop client to a web browser. However, due to limitations in browsers, there are certain features in the desktop client that cannot be reproduced exactly. This version of the i2b2 web client includes the following cells and views:
Project Management Cell
Login to the web client with the same username and password as the desktop client. If you have access to multiple projects, you can select the one you want to use when you login.
Ontology Cell
Use the Navigate Terms and Find Terms views to locate the medical concepts that you can query.
Clinical Research Chart Cell
The CRC cell stores patient data and consists of several views. The Query Tool view allows you to define a query. Drag and drop concepts from the Ontology Cell onto the Query Tool to build arbitrarily complex Boolean expressions. When you run a query, the results are displayed in the Query Status view, and the query definition is automatically added to the Previous Queries view. In the Previous Queries view, you can also drill down to view the results of past queries. To view a previous query definition, drag and drop its folder onto the Query Tool view.
 You have both a private place to store objects as well as a shared directory, which can be accessed by anyone in the project.
Analysis Tools
The i2b2 web client contains an Analysis Tools page that provides a collection of plugins that perform a variety of data analysis and visualization functions. The Plugins view lists the available plugins for your project. Click any plugin to load it into the Plugin Viewer. Some plugins contain additional help information for using that plugin.
About Us
The i2b2 web client was designed and built by Nick Benik from the Information Technology Department at Harvard Medical School and Griffin Weber, MD, PhD, who is the Chief Technology Officer of Harvard Medical School and a faculty member in the Division of Interdisciplinary Medicine and Biotechnology at Beth Israel Deaconess Medical Center in Boston, Massachusetts. We thank the i2b2 team at Partners HealthCare System for their assistance in creating this web client. For additional information about i2b2, please contact Susanne Churchill at schurchill@partners.org.


An open journal-- some of it written for you, but most of it is for me.
Ruby Collections and Enumerators – David Black
Ruby Collections and Enumerators
David Black
June 26, 2012
Enumerators
- what is an enum?
- an instance of class Enum
-external iterator
-iterates via a specific method on an underlying object
??next method- walk through the iteration and give you the next value
the default bound is the each method
%w –> converst to enum
loop resuces the stop Iteration error
??each_cons method
if you run each on enum = array.map # => it behaves like map
same with array.select and array.each_cons
Can also chain enumerators:
array.each.with_index #=> will yield the index
array.map.with_index
.extend(Enumerable)#=> extends the Enum functionality if operating on a single objecteach_slice# doesn't overlap like each_consrequire'prime'#there is a Prime class array.any?# --> is there anything True in this array?array.none?array.one?# (just one-- will exit after it's first hit)array.all?array=[a,3,2,4,5,6,7]array.partition{blockthatcallstheevenmethod}#=> wtih divide the result into two arrays a true an otherarray.slice_before#=> [[1,3], [2], [4,5,7], [6]]chunkdiscardsresultsforwhichtheblockevaluatestonil#=> not useful- obscure methodarray.takearray.droptake_while#=> e.g. while true execute belowdrop_whilearray=[1,2,3]array.permutation.to_a# => yields all the permuatations of the array [[1,2,3], [1,3,2], [2,1,3]]array.combination(2).to_a#=> yields the combinations (in this case 2 at a time [1,2], [1,3], [2,3])array.sample#=> pulls a random sample from the arrayarray.shuffle# => will randomize the sample


| I l@ve RuBoard |
7.5 Binding EventsWe met the bind widget method in the last chapter, when we used it to catch button presses in the tutorial. Because bind is commonly used in conjunction with other widgets (e.g., to catch return key presses for input boxes), we're going to make a stop early on the tour here as well. Example 7-15 illustrates more bind event protocols. Example 7-15. PP2E\Gui\Tour\bind.pyfrom Tkinter import * def showPosEvent(event): print 'Widget=%s X=%s Y=%s' % (event.widget, event.x, event.y) def showAllEvent(event): print event for attr in dir(event): print attr, '=>', getattr(event, attr) def onKeyPress(event): print 'Got key press:', event.char def onArrowKey(event): print 'Got up arrow key press' def onReturnKey(event): print 'Got return key press' def onLeftClick(event): print 'Got left mouse button click:', showPosEvent(event) def onRightClick(event): print 'Got right mouse button click:', showPosEvent(event) def onMiddleClick(event): print 'Got middle mouse button click:', showPosEvent(event) showAllEvent(event) def onLeftDrag(event): print 'Got left mouse button drag:', showPosEvent(event) def onDoubleLeftClick(event): print 'Got double left mouse click', showPosEvent(event) tkroot.quit() tkroot = Tk() labelfont = ('courier', 20, 'bold') # family, size, style widget = Label(tkroot, text='Hello bind world') widget.config(bg='red', font=labelfont) # red background, large font widget.config(height=5, width=20) # initial size: lines,chars widget.pack(expand=YES, fill=BOTH) widget.bind('<Button-1>', onLeftClick) # mouse button clicks widget.bind('<Button-3>', onRightClick) widget.bind('<Button-2>', onMiddleClick) # middle=both on some mice widget.bind('<Double-1>', onDoubleLeftClick) # click left twice widget.bind('<B1-Motion>', onLeftDrag) # click left and move widget.bind('<KeyPress>', onKeyPress) # all keyboard presses widget.bind('<Up>', onArrowKey) # arrow button pressed widget.bind('<Return>', onReturnKey) # return/enter key pressed widget.focus() # or bind keypress to tkroot tkroot.title('Click Me') tkroot.mainloop() Most of this file consists of callback handler functions triggered when bound events occur. As we learned in Chapter 6, these callbacks all receive an event object argument that gives details about the event that fired. Technically, this argument is an instance of the Tkinter Event class, and its details are attributes; most of the callbacks simply trace events by displaying relevant event attributes. When run, this script makes the window shown in Figure 7-20; it's mostly intended just as a surface for clicking and pressing event triggers. Figure 7-20. A bind window for the clickingThe black-and-white medium of the book you're holding won't really do justice to this script -- when run live, it uses the configuration options shown earlier to make the window show up as black on red, with a large Courier font.  But the main point of this example is to demonstrate other kinds of event binding protocols at work. We saw a script that intercepted left and double-left mouseclicks with the widget bind method earlier; the script here demonstrates other kinds of events that are commonly caught with bind:
Here is what shows up in the stdout output stream, after a left click, right click, left click and drag, a few key presses, a Return and up-arrow press, and a final double-left click to exit. When you press the left mouse button and drag it around on the display, you'll get lots of drag event messages -- one is printed for every move during the drag (and one Python callback is run for each): C:\...\PP2E\Gui\Tour>python bind.py Got left mouse button click: Widget=.7871632 X=209 Y=79 Got right mouse button click: Widget=.7871632 X=209 Y=79 Got left mouse button click: Widget=.7871632 X=83 Y=63 Got left mouse button drag: Widget=.7871632 X=83 Y=65 Got left mouse button drag: Widget=.7871632 X=84 Y=66 Got left mouse button drag: Widget=.7871632 X=85 Y=66 Got left mouse button drag: Widget=.7871632 X=85 Y=67 Got left mouse button drag: Widget=.7871632 X=85 Y=68 Got key press: s Got key press: p Got key press: a Got key press: m Got key press: 1 Got key press: - Got key press: 2 Got key press: . Got return key press Got up arrow key press Got left mouse button click: Widget=.7871632 X=85 Y=68 Got double left mouse click Widget=.7871632 X=85 Y=68 For mouse-related events, callbacks print the X and Y coordinates of the mouse pointer, in the event object passed in. Coordinates are usually measured in pixels from the upper-left corner (0,0), but are relative to the widget being clicked. Here's what is printed for a left, middle, and double-left click. Notice that the middle-click callback dumps the entire argument -- all of the Event object's attributes. Different event types set different event attributes; most key presses put something in char, for instance: C:\...\PP2E\Gui\Tour>python bind.py Got left mouse button click: Widget=.7871632 X=163 Y=18 Got middle mouse button click: Widget=.7871632 X=152 Y=110 <Tkinter.Event instance at 7b3640> char => ?? height => 0 keycode => 2 keysym => ?? keysym_num => 2 num => 2 send_event => 0 serial => 14 state => 0 time => 5726238 type => 4 widget => .7871632 width => 0 x => 152 x_root => 156 y => 110 y_root => 133 Got left mouse button click: Widget=.7871632 X=152 Y=110 Got double left mouse click Widget=.7871632 X=152 Y=110 Besides the ones illustrated in this example, there are additional kinds of bindable events that a Tkinter script can register to catch. For example:
This is not a complete list, and event names can be written with a somewhat sophisticated syntax all their own. For example:
In the interest of space, though, we'll defer to other Tk and Tkinter reference sources for an exhaustive list of details on this front. Alternatively, changing some of the settings in the example script and rerunning can help clarify some event behavior too; this is Python, after all. |
| I l@ve RuBoard |


"""Validation of dependencies of packages """ # The following comment should be removed at some point in the future. # mypy: strict-optional=False # mypy: disallow-untyped-defs=False import logging from collections import namedtuple from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.pkg_resources import RequirementParseError from pip._internal.distributions import ( make_distribution_for_install_requirement, ) from pip._internal.utils.misc import get_installed_distributions from pip._internal.utils.typing import MYPY_CHECK_RUNNING logger = logging.getLogger(__name__) if MYPY_CHECK_RUNNING: from pip._internal.req.req_install import InstallRequirement from typing import ( Any, Callable, Dict, Optional, Set, Tuple, List ) # Shorthands PackageSet = Dict[str, 'PackageDetails'] Missing = Tuple[str, Any] Conflicting = Tuple[str, str, Any] MissingDict = Dict[str, List[Missing]] ConflictingDict = Dict[str, List[Conflicting]] CheckResult = Tuple[MissingDict, ConflictingDict] PackageDetails = namedtuple('PackageDetails', ['version', 'requires']) def create_package_set_from_installed(**kwargs): # type: (**Any) -> Tuple[PackageSet, bool] """Converts a list of distributions into a PackageSet. """ # Default to using all packages installed on the system if kwargs == {}: kwargs = {"local_only": False, "skip": ()} package_set = {} problems = False for dist in get_installed_distributions(**kwargs): name = canonicalize_name(dist.project_name) try: package_set[name] = PackageDetails(dist.version, dist.requires()) except RequirementParseError as e: # Don't crash on broken metadata logger.warning("Error parsing requirements for %s: %s", name, e) problems = True return package_set, problems def check_package_set(package_set, should_ignore=None): # type: (PackageSet, Optional[Callable[[str], bool]]) -> CheckResult """Check if a package set is consistent If should_ignore is passed, it should be a callable that takes a package name and returns a boolean. """ if should_ignore is None: def should_ignore(name): return False missing = {} conflicting = {} for package_name in package_set: # Info about dependencies of package_name missing_deps = set() # type: Set[Missing] conflicting_deps = set() # type: Set[Conflicting] if should_ignore(package_name): continue for req in package_set[package_name].requires: name = canonicalize_name(req.project_name) # type: str # Check if it's missing if name not in package_set: missed = True if req.marker is not None: missed = req.marker.evaluate() if missed: missing_deps.add((name, req)) continue # Check if there's a conflict version = package_set[name].version # type: str if not req.specifier.contains(version, prereleases=True): conflicting_deps.add((name, version, req)) if missing_deps: missing[package_name] = sorted(missing_deps, key=str) if conflicting_deps: conflicting[package_name] = sorted(conflicting_deps, key=str) return missing, conflicting def check_install_conflicts(to_install): # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult] """For checking if the dependency graph would be consistent after \ installing given requirements """ # Start from the current state package_set, _ = create_package_set_from_installed() # Install packages would_be_installed = _simulate_installation_of(to_install, package_set) # Only warn about directly-dependent packages; create a whitelist of them whitelist = _create_whitelist(would_be_installed, package_set) return ( package_set, check_package_set( package_set, should_ignore=lambda name: name not in whitelist ) ) def _simulate_installation_of(to_install, package_set): # type: (List[InstallRequirement], PackageSet) -> Set[str] """Computes the version of packages after installing to_install. """ # Keep track of packages that were installed installed = set() # Modify it as installing requirement_set would (assuming no errors) for inst_req in to_install: abstract_dist = make_distribution_for_install_requirement(inst_req) dist = abstract_dist.get_pkg_resources_distribution() name = canonicalize_name(dist.key) package_set[name] = PackageDetails(dist.version, dist.requires()) installed.add(name) return installed def _create_whitelist(would_be_installed, package_set): # type: (Set[str], PackageSet) -> Set[str] packages_affected = set(would_be_installed) for package_name in package_set: if package_name in packages_affected: continue for req in package_set[package_name].requires: if canonicalize_name(req.name) in packages_affected: packages_affected.add(package_name) break return packages_affected


Pig Latin Translator
Catagory: Programing
Date Completed: 8/14/13
Developers: Noah Huppert
Download
Lately I have been experimenting with varous methods of encryption. I have tried PGP for email both on android using APG and K9-Mail and on the desktop using a wonderfull chrome plugin
Mymail-Crypt for Gmail. So I thought I would give encrytion a try, except on a lower level.
Date Completed: 8/14/13
Developers: Noah Huppert
Download
I present to you, the Pig Latin Translator:
How to use:
- Type in your phrase to translate into Pig Latin
- Optional: change the method of Pig Latin Encryption for ending in "A" or "Ay"
- Hit "Translate"
- Optional: click "Piglatin" or "English" to change the box input types so you can translate from Piglatin to English
Pig Latin Translater
A: Piglatin -> iglatinpay
Ay: Piglatin -> iglatinpa
English
PigLatin
Translate
Coded By Noah Huppert


Before Change
sys.path.append(os.path.join(os.path.dirname(frameworkDir),"scripts","TestHarness","testers"))
import RavenUtils
sys.path.pop() //remove testers path
missing,outOfRange,notQA = RavenUtils.check_for_missing_modules(False)
if len(missing) + len(outOfRange) > 0 and RavenUtils.check_versions():
print("ERROR: too old, too new, or missing raven libraries, not running:")
for error in missing + outOfRange + notQA:
print(error)
After Change
return
// otherwise, we check for incorrect libraries
missing, notQA = LH.checkLibraries()
if missing:
print("ERROR: Some required Python libraries are missing but required to run RAVEN as configured:")
for lib, version in missing:
// report the missing library
msg = " -> MISSING: {}".format(lib)
// add the required version if applicable
if version is not None:
msg += " version {}".format(version)
print(msg)
if notQA:
print("ERROR: Some required Python libraries have incorrect versions for running RAVEN as configured:")
for lib, found, need in notQA:
print(" -> WRONG VERSION: lib "{}" need "{}" but found "{}"".format(lib, found, need))


| 1 |
Wallace_2014 |
Geographic Access to High Capability Severe Acute Respiratory Failure Centers in the United States |
Wallace, David J.; Angus, Derek C.; Seymour, Christopher W.; Yealy, Donald M.; Carr, Brendan G.; Kurland, Kristen; Boujoukos, Arthur; Kahn, Jeremy M. |
2014 |
2014-04-04 |
COMM-USE |
N |
PMC3976413 |
24705417.0 |
10.1371/journal.pone.0094057 |
rmmci8g1 |
0.804977 |
Laurens_2019, Atkinson_2020 |
|
| 2 |
Lacasa_2020 |
A flexible load sharing system and implementation to anticipate and organise transfers based on ICU demand in the context of COVID-19 pandemic |
Lucas Lacasa; Robert Challen; Ellen Brooks-Pollock; Leon Danon |
2020 |
2020-04-03 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>49239 |
qcr347de |
0.754502 |
Mwabu_2008, Amirov_2007, Rubinson_2005 |
Mehrotra_2020, Weissman_2020, Massonnaud_2020, Zhang_2020 |
| 3 |
Rubinson_2005 |
Critical care during epidemics |
Rubinson, Lewis; O'Toole, Tara |
2005 |
2005-04-27 |
PMC |
N |
PMC1269436 |
16137366.0 |
10.1186/cc3533 |
wzun1vvq |
0.740895 |
Laurens_2019, Atkinson_2020, Amirov_2007 |
Rubinson_2008, Adhikari_2010, Maves_2019, Challen_2007 |
| 4 |
Castro_2020 |
Demand for hospitalization services for COVID-19 patients in Brazil |
Marcia C Castro; Lucas Resende de Carvalho; Taylor Chin; Rebecca Kahn; Giovanny V. A. Franca; Eduardo Marques Macario; Wanderson Kleber de Oliveira |
2020 |
2020-04-01 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>47662 |
nqauuzw0 |
0.727749 |
Atkinson_2020, Laurens_2019 |
Zhang_2020 |
| 5 |
Branas_2020 |
Flattening the curve before it flattens us: hospital critical care capacity limits and mortality from novel coronavirus (SARS-CoV2) cases in US counties |
Charles C Branas; Andrew Rundle; Sen Pei; Wan Yang; Brendan G Carr; Sarah Sims; Alexis Zebrowski; Ronan Doorley; Neil Schluger; James W Quinn; Jeffrey Shaman |
2020 |
2020-04-06 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>49759 |
b23301ac |
0.690969 |
Atkinson_2020, Laurens_2019 |
Zhang_2020, Massonnaud_2020 |
| 6 |
Francis_2020 |
Projected ICU and Mortuary load due to COVID-19 in Sydney |
Andrew Francis; Yi Guo; Paul Hurley; Oliver Obst; Laurence A. F. Park; Mark Tanaka; Russell Thomson; Rosalind Wang |
2020 |
2020-04-03 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>49312 |
q9a374hh |
0.677483 |
Amirov_2007, Laurens_2019 |
Li_N_2020 |
| 7 |
Weissman_2020 |
Locally Informed Simulation to Predict Hospital Capacity Needs During the COVID-19 Pandemic |
Weissman, Gary E.; Crane-Droesch, Andrew; Chivers, Corey; Luong, ThaiBinh; Hanish, Asaf; Levy, Michael Z.; Lubken, Jason; Becker, Michael; Draugelis, Michael E.; Anesi, George L.; Brennan, Patrick J.; Christie, Jason D.; Hanson III, C. William; Mikkelsen, Mark E.; Halpern, Scott D. |
2020 |
2020-04-07 |
None |
Y |
PMC7153364 |
32259197.0 |
10.7326/m20-1260 |
jkyltjap |
0.645743 |
Laurens_2019, Amirov_2007 |
Massonnaud_2020, Zhang_2020, Castro_2020 |
| 8 |
Zhang_2020 |
A model to estimate bed demand for COVID-19 related hospitalization |
Teng Zhang; Kelly McFarlane; Jacqueline Vallon; Linying Yang; Jin Xie; Jose Blanchet; Peter Glynn; Kristan Staudenmayer; Kevin Schulman; David Scheinker |
2020 |
2020-03-26 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>42762 |
eee22bzx |
0.637714 |
Mwabu_2008, Amirov_2007 |
Castro_2020 |
| 9 |
Fowler_2015 |
Critical care capacity in Canada: results of a national cross-sectional study |
Fowler, Robert A; Abdelmalik, Philip; Wood, Gordon; Foster, Denise; Gibney, Noel; Bandrauk, Natalie; Turgeon, Alexis F; Lamontagne, François; Kumar, Anand; Zarychanski, Ryan; Green, Rob; Bagshaw, Sean M; Stelfox, Henry T; Foster, Ryan; Dodek, Peter; Shaw, Susan; Granton, John; Lawless, Bernard; Hill, Andrea; Rose, Louise; Adhikari, Neill K; Scales, Damon C; Cook, Deborah J; Marshall, John C; Martin, Claudio; Jouvet, Philippe |
2015 |
2015-04-01 |
None |
N |
PMC4426537 |
25888116.0 |
10.1186/s13054-015-0852-6 |
drtviivx |
0.631298 |
Laurens_2019, Amirov_2007, Atkinson_2020 |
Fausto_2020, Castro_2020, Rubinson_2008 |
| 10 |
Massonnaud_2020 |
COVID-19: Forecasting short term hospital needs in France |
Clément Massonnaud; Jonathan Roux; Pascal Crépey |
2020 |
2020-03-20 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>36939 |
i46n70gb |
0.619786 |
Amirov_2007, Atkinson_2020 |
Zhang_2020 |
| 11 |
Khera_2020 |
Evaluation of the Anticipated Burden of COVID-19 on Hospital-Based Healthcare Services Across the United States |
Rohan Khera; Snigdha Jain; Zhenqiu Lin; Joseph S. Ross; Harlan Krumholz |
2020 |
2020-04-03 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>50492 |
g6zeoth6 |
0.606311 |
Laurens_2019 |
|
| 12 |
Ferstad_2020 |
A model to forecast regional demand for COVID-19 related hospital beds |
Johannes Opsahl Ferstad; Angela Jessica Gu; Raymond Ye Lee; Isha Thapa; Andrew Y Shin; Joshua A Salomon; Peter Glynn; Nigam H Shah; Arnold Milstein; Kevin Schulman; David Scheinker |
2020 |
2020-03-30 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>44842 |
jjtsd4n3 |
0.601092 |
Mwabu_2008, Amirov_2007 |
Zhang_2020, Weissman_2020, Massonnaud_2020, Castro_2020 |
| 13 |
Mehrotra_2020 |
A Model for Supply-Chain Decisions for Resource Sharing with an Application to Ventilator Allocation to Combat COVID-19 |
Sanjay Mehrotra; Hamed Rahimian; Masoud Barah; Fengqiao Luo; Karolina Schantz |
2020 |
2020-04-06 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>51078 |
6ixjbbek |
0.596085 |
|
Castro_2020, Lacasa_2020, Pecoraro_2020 |
| 14 |
Rubinson_2008 |
Definitive Care for the Critically Ill During a Disaster: A Framework for Optimizing Critical Care Surge Capacity From a Task Force for Mass Critical Care Summit Meeting, January 26–27, 2007, Chicago, IL |
Rubinson, Lewis; Hick, John L.; Hanfling, Dan G.; Devereaux, Asha V.; Dichter, Jeffrey R.; Christian, Michael D.; Talmor, Daniel; Medina, Justine; Curtis, J. Randall; Geiling, James A. |
2008 |
2008-05-31 |
PMC |
N |
PMC7094361 |
18460504.0 |
10.1378/chest.07-2690 |
v0booj4n |
0.584872 |
Laurens_2019, Amirov_2007, Atkinson_2020 |
Rubinson_2008, Christian_2008, Hawryluck_2005, Wax_R_2019 |
| 15 |
Nap_R_2007 |
Pandemic Influenza and Hospital Resources |
Nap, Raoul E.; Andriessen, Maarten P.H.M.; Meessen, Nico E.L.; van der Werf, Tjip S. |
2007 |
2007-11-23 |
PMC |
N |
PMC3375786 |
18217556.0 |
10.3201/eid1311.070103 |
1f2n8p01 |
0.546558 |
Atkinson_2020, Amirov_2007, Laurens_2019 |
Castro_2020, Nap_R_2008 |
| 16 |
Christian_2008 |
Definitive Care for the Critically Ill During a Disaster: Current Capabilities and Limitations From a Task Force for Mass Critical Care Summit Meeting, January 26–27, 2007, Chicago, IL |
Christian, Michael D.; Devereaux, Asha V.; Dichter, Jeffrey R.; Geiling, James A.; Rubinson, Lewis |
2008 |
2008-05-31 |
PMC |
N |
PMC7094433 |
18460503.0 |
10.1378/chest.07-2707 |
m8i3q9ww |
0.543083 |
Atkinson_2020, Amirov_2007 |
Rubinson_2008, Rubinson_2008, Hawryluck_2005, Edwards_2007 |
| 17 |
Wunsch_2012 |
Is There a Starling Curve for Intensive Care? |
Wunsch, Hannah |
2012 |
2012-06-30 |
None |
N |
PMC3367487 |
22670019.0 |
10.1378/chest.11-2819 |
961bddej |
0.536899 |
Atkinson_2020, Rubinson_2005 |
Hargrove_2005, Castro_2020, Schwartz_2012 |
| 18 |
Pecoraro_2020 |
The efficiency in the ordinary hospital bed management in Italy: an in-depth analysis of intensive care unit in the areas affected by COVID-19 before the outbreak |
Fabrizio Pecoraro; Fabrizio Clemente; Daniela Luzi |
2020 |
2020-04-11 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>55848 |
ec3kyasm |
0.505973 |
Laurens_2019, Atkinson_2020 |
Castro_2020, Dubost_2015 |
| 19 |
Srinivasan_2020 |
Individualized System for Augmenting Ventilator Efficacy (iSAVE): A Rapidly deployable system to expand ventilator capacity |
Shriya Srinivasan; Khalil Ramadi; Franceso Vicario; Declan Gwynne; Alison Hayward; Robert Langer; Joseph Frassica; Rebecca Baron; Giovanni Traverso |
2020 |
2020-03-29 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>617 |
aarthz9w |
0.502072 |
Amirov_2007, Mwabu_2008, Atkinson_2020, Rubinson_2005 |
|
| 20 |
Rubinson_2008 |
Definitive Care for the Critically Ill During a Disaster: Medical Resources for Surge Capacity From a Task Force for Mass Critical Care Summit Meeting, January 26–27, 2007, Chicago, IL |
Rubinson, Lewis; Hick, John L.; Curtis, J. Randall; Branson, Richard D.; Burns, Suzi; Christian, Michael D.; Devereaux, Asha V.; Dichter, Jeffrey R.; Talmor, Daniel; Erstad, Brian; Medina, Justine; Geiling, James A. |
2008 |
2008-05-31 |
PMC |
N |
PMC7094478 |
18460505.0 |
10.1378/chest.07-2691 |
xnwbjl46 |
0.498761 |
Laurens_2019, Amirov_2007 |
Rubinson_2008, Christian_2008, Hawryluck_2005, King_2014 |
| 21 |
Iwashyna_2009 |
Uncharted Paths Hospital Networks in Critical Care |
Iwashyna, Theodore J.; Christie, Jason D.; Kahn, Jeremy M.; Asch, David A. |
2009 |
2009-03-31 |
None |
N |
PMC2692049 |
19265091.0 |
10.1378/chest.08-1052 |
89mbwzme |
0.498423 |
Atkinson_2020, Laurens_2019, Amirov_2007 |
Fausto_2020, Hick_2004, Castro_2020 |
| 22 |
Challen_2007 |
Clinical review: Mass casualty triage – pandemic influenza and critical care |
Challen, Kirsty; Bentley, Andrew; Bright, John; Walter, Darren |
2007 |
2007-04-30 |
PMC |
N |
PMC2206465 |
17490495.0 |
10.1186/cc5732 |
mzn448zk |
0.476922 |
Amirov_2007, Atkinson_2020, Mwabu_2008 |
Fausto_2020, Adhikari_2010, Rubinson_2008, Hargrove_2005 |
| 23 |
Adhikari_2010 |
Critical care and the global burden of critical illness in adults |
Adhikari, Neill KJ; Fowler, Robert A; Bhagwanjee, Satish; Rubenfeld, Gordon D |
2010 |
2010-10-22 |
PMC |
N |
PMC7136988 |
20934212.0 |
10.1016/s0140-6736(10)60446-1 |
ljx13yd6 |
0.474156 |
Atkinson_2020, Amirov_2007 |
Fausto_2020, Rubinson_2008, Diaz_2019 |
| 24 |
Nap_R_2008 |
Pandemic Influenza and Excess Intensive-Care Workload |
Nap, Raoul E.; Andriessen, Maarten P.H.M.; Meessen, Nico E.L.; dos Reis Miranda, Dinis; van der Werf, Tjip S. |
2008 |
2008-10-23 |
None |
N |
PMC2609860 |
18826813.0 |
10.3201/eid1410.080440 |
qlittfxl |
0.457975 |
Atkinson_2020, Amirov_2007, Laurens_2019 |
Rebmann_2007, Castro_2020, Wang_2020 |
| 25 |
Culmer_2020 |
Delivering oxygen-enriched CPAP respiratory support using a non-invasive ventilation device |
Peter Culmer; Steven Ashton; Martin Latham; Stuart Murdoch; David Brettle; Nikil Kapur |
2020 |
2020-04-11 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>55665 |
xs9lot5s |
0.456374 |
Amirov_2007, Mwabu_2008 |
|
| 26 |
Curiel-Balsera_2013 |
Guidelines for Health Organizations: European Perspectives and Experience in Pandemics |
Curiel-Balsera, Emilio; García-Trujillo, Elena |
2013 |
2013-05-29 |
PMC |
N |
PMC7122448 |
|
10.1007/978-3-7091-1496-4_41 |
kfl6xt31 |
0.449362 |
Laurens_2019, Atkinson_2020, Amirov_2007 |
Castro_2020, Wang_2020 |
| 27 |
Rivera-Rodriguez_2020 |
Modelling strategies to predict hospital demand during the COVID-19 outbreak in Bogotá, Colombia |
Claudia Rivera-Rodriguez; Beatriz Piedad Urdinola |
2020 |
2020-04-18 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>65466 |
6qfryfnt |
0.449055 |
Amirov_2007 |
|
| 28 |
Hargrove_2005 |
Bench-to-bedside review: Outcome predictions for critically ill patients in the emergency department |
Hargrove, Jenny; Nguyen, H Bryant |
2005 |
2005-04-18 |
PMC |
N |
PMC1269432 |
16137387.0 |
10.1186/cc3518 |
fkigak9x |
0.448600 |
Laurens_2019, Atkinson_2020, Amirov_2007, Diaz_2019, Rubinson_2005 |
|
| 29 |
Dort_2017 |
Improving the Hospital Quality of Care during Winter Periods by Optimizing Budget Allocation Between Rotavirus Vaccination and Bed Expansion |
Dort, Thibaut; Schecroun, Nadia; Standaert, Baudouin |
2017 |
2017-11-20 |
NONCOMM |
N |
PMC5797246 |
29159785.0 |
10.1007/s40258-017-0362-6 |
tmydzyiq |
0.416150 |
Atkinson_2020, Laurens_2019 |
Pecoraro_2020, Castro_2020, Dorzin_2017 |
| 30 |
Verelst_2020 |
Indications for healthcare surge capacity in European countries facing an exponential increase in coronavirus disease (COVID-19) cases, March 2020 |
Verelst, Frederik; Kuylen, Elise; Beutels, Philippe |
2020 |
2020-04-02 |
COMM-USE |
Y |
PMC7140594 |
32265003.0 |
10.2807/1560-7917.es.2<IP_ADDRESS>0323 |
4msw4cdb |
0.410006 |
|
Boettler_2020, Kinross_2020 |
| 31 |
Bambi_2017 |
Evolution of Intensive Care Unit Nursing |
Bambi, Stefano |
2017 |
2017-10-06 |
PMC |
N |
PMC7123277 |
|
10.1007/978-3-319-50559-6_19 |
kv3vxmcw |
0.401398 |
Laurens_2019, Atkinson_2020, Amirov_2007 |
Wang_2020, Hargrove_2005, Fausto_2020 |
| 32 |
Hick_2004 |
Health care facility and community strategies for patient care surge capacity |
Hick, John L.; Hanfling, Dan; Burstein, Jonathan L.; DeAtley, Craig; Barbisch, Donna; Bogdan, Gregory M.; Cantrill, Stephen |
2004 |
2004-09-30 |
PMC |
N |
PMC7118880 |
15332068.0 |
10.1016/j.annemergmed.2004.04.011 |
6abs647e |
0.393883 |
|
Rebmann_2007, Hawryluck_2005, Rubinson_2008, Edwards_2007 |
| 33 |
Downar_2010 |
Palliating a Pandemic: “All Patients Must Be Cared For” |
Downar, James; Seccareccia, Dori |
2010 |
2010-02-28 |
PMC |
N |
PMC7135517 |
20152591.0 |
10.1016/j.jpainsymman.2009.11.241 |
8hnzx44p |
0.390072 |
Atkinson_2020, Amirov_2007 |
Fausto_2020, Ferguson_2020, Adams_2020, Rubinson_2008 |
| 34 |
Turner_2016 |
A Review of Pediatric Critical Care in Resource-Limited Settings: A Look at Past, Present, and Future Directions |
Turner, Erin L.; Nielsen, Katie R.; Jamal, Shelina M.; von Saint André-von Arnim, Amelie; Musa, Ndidiamaka L. |
2016 |
2016-02-18 |
COMM-USE |
N |
PMC4757646 |
26925393.0 |
10.3389/fped.2016.00005 |
zu9a0tfq |
0.382582 |
Atkinson_2020 |
Diaz_2019, Adhikari_2010 |
| 35 |
Chopra_2020 |
How Should U.S. Hospitals Prepare for Coronavirus Disease 2019 (COVID-19)? |
Chopra, Vineet; Toner, Eric; Waldhorn, Richard; Washer, Laraine |
2020 |
2020-03-11 |
PMC |
Y |
PMC7081177 |
32160273.0 |
10.7326/m20-0907 |
tyobde1j |
0.378912 |
Atkinson_2020, Laurens_2019 |
|
| 36 |
Damji_2005 |
An audit of the use of isolation facilities in a UK National Health Service trust |
Damji, S.; Barlow, G.D.; Patterson, L.; Nathwani, D. |
2005 |
2005-07-31 |
PMC |
N |
PMC7132430 |
15949612.0 |
10.1016/j.jhin.2004.11.013 |
o6tuulli |
0.378037 |
Laurens_2019, Amirov_2007, Atkinson_2020 |
Cunney_2006 |
| 37 |
Thampi_2012 |
Pro/Con debate: Are barrier precautions cost-effective in improving patient outcomes in the intensive care unit? |
Thampi, Nisha; Morris, Andrew M |
2012 |
2012-01-19 |
PMC |
N |
PMC3396214 |
22264293.0 |
10.1186/cc10532 |
w8579f54 |
0.376779 |
Atkinson_2020 |
Farr_2004, Coccolini_2020 |
| 38 |
Bohn_2011 |
Supplies and equipment for pediatric emergency mass critical care |
Bohn, Desmond; Kanter, Robert K.; Burns, Jeffrey; Barfield, Wanda D.; Kissoon, Niranjan |
2011 |
2011-11-01 |
PMC |
N |
PMC4561174 |
22067920.0 |
10.1097/pcc.0b013e318234a6b9 |
g3223ze8 |
0.372164 |
|
Rubinson_2008, Edwards_2007, Rubinson_2008, Rebmann_2007 |
| 39 |
Rosenberg_2010 |
The most influential articles in critical care medicine |
Rosenberg, Andrew L.; Tripathi, Ravi S.; Blum, James |
2010 |
2010-03-31 |
PMC |
N |
PMC7127294 |
19327953.0 |
10.1016/j.jcrc.2008.12.010 |
41hjajw3 |
0.367366 |
|
|
| 40 |
Robinson_2020 |
A modification to the Maquet Flow-i anaesthesia machine for ICU ventilation |
Andrew J Robinson; William London; Lazslo Kotan; Warwick Downing |
2020 |
2020-04-11 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>54882 |
l3d1dc93 |
0.364361 |
Amirov_2007 |
|
| 41 |
Cooper_2005 |
Communication of bed allocation decisions in a critical care unit and accountability for reasonableness |
Cooper, Andrew B; Joglekar, Amit S; Gibson, Jennifer; Swota, Alissa H; Martin, Douglas K |
2005 |
2005-10-31 |
COMM-USE |
N |
PMC1298296 |
16259634.0 |
10.1186/1472-6963-5-67 |
4azsywuu |
0.349558 |
|
Dudgeon_2008, Tzeng_2016, Wilson_2020 |
| 42 |
Ramtoola_2019 |
A case report of a ruptured subclavian artery aneurysm presenting to the emergency department |
Ramtoola, Mohammad Tariq; Bhatti, Mubashir; Shetty, Ritesh |
2019 |
2019-03-12 |
NONCOMM |
N |
PMC6452447 |
30997088.0 |
10.1002/ccr3.2098 |
ntynqlbp |
0.339950 |
Laurens_2019, Atkinson_2020, Amirov_2007, Downar_2010 |
|
| 43 |
Schooling_2020 |
Forecasting Hospital Staff Availability During The COVID-19 Epidemic |
Chloe N Schooling; Norbert Gyenge; Visakan Kadirkamanathan; James J.P. Alix |
2020 |
2020-04-17 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>66019 |
e1iek3jx |
0.339328 |
Amirov_2007, Mwabu_2008, Atkinson_2020 |
|
| 44 |
Diaz_2019 |
Global Critical Care: Moving Forward in Resource-Limited Settings |
Diaz, Janet V.; Riviello, Elisabeth D.; Papali, Alfred; Adhikari, Neill K. J.; Ferreira, Juliana C. |
2019 |
2019-01-22 |
COMM-USE |
N |
PMC7052346 |
30741504.0 |
10.5334/aogh.2413 |
trcisop6 |
0.332471 |
Amirov_2007 |
Adhikari_2010, Turner_2016 |
| 45 |
Badawi_2020 |
Impact of COVID-19 pandemic on severity of illness and resources required during intensive care in the greater New York City area |
Omar Badawi; Xinggang Liu; Iris Berman; Pamela J Amelung; Martin Doerfler; Saurabh Chandra |
2020 |
2020-04-14 |
BioRxiv |
Y |
|
|
10.1101/2<IP_ADDRESS>58180 |
54auaa78 |
0.327955 |
Laurens_2019, Yeh_S_2005, Ishizaki_2004 |
Castro_2020 |
| 46 |
Mwabu_2008 |
The Demand for Health Care |
Mwabu, G. |
2008 |
2008-12-31 |
PMC |
N |
PMC7149721 |
|
10.1016/b978-012373960-5.00164-7 |
f4x85a3g |
0.326032 |
|
Yip_W_2014, Kang_2003 |
| 47 |
Angus_2004 |
Improving care of the critically ill: institutional and health-care system approaches |
Angus, Derek C; Black, Nick |
2004 |
2004-04-17 |
PMC |
N |
PMC7124584 |
15094279.0 |
10.1016/s0140-6736(04)16007-8 |
dvd32fc2 |
0.311701 |
Amirov_2007 |
Wilson_2020, Diaz_2019, Fausto_2020 |
| 48 |
Kinross_2020 |
Rapidly increasing cumulative incidence of coronavirus disease (COVID-19) in the European Union/European Economic Area and the United Kingdom, 1 January to 15 March 2020 |
Kinross, Pete; Suetens, Carl; Gomes Dias, Joana; Alexakis, Leonidas; Wijermans, Ariana; Colzani, Edoardo; Monnet, Dominique L. |
2020 |
2020-03-19 |
COMM-USE |
Y |
PMC7096777 |
32186277.0 |
10.2807/1560-7917.es.2<IP_ADDRESS>0285 |
r74u7oyo |
0.310389 |
Laurens_2019, Atkinson_2020 |
|
| 49 |
Braithwaite_2013 |
Microsimulation of Financial Impact of Demand Surge on Hospitals: The H1N1 Influenza Pandemic of Fall 2009 |
Braithwaite, Sabina; Friedman, Bernard; Mutter, Ryan; Handrigan, Michael |
2013 |
2013-02-10 |
PMC |
N |
PMC3626336 |
23398540.0 |
10.1111/1475-6773.12041 |
7648wyxb |
0.308090 |
Laurens_2019, Jeffery_2013 |
Castro_2020 |
| 50 |
Dara_2005 |
Engendering enthusiasm for sustainable disaster critical care response: why this is of consequence to critical care professionals? |
Dara, Saqib I; Ashton, Rendell W; Farmer, J Christopher |
2005 |
2005-01-27 |
PMC |
N |
PMC1175928 |
15774058.0 |
10.1186/cc3048 |
fooovon8 |
0.300091 |
Atkinson_2020, Amirov_2007 |
Hawryluck_2005, Rubinson_2008, Wax_R_2019, Kearns_2017 |


b@ld
give me @ touch
Pedro Nuno Parreira e Silva
Multimedia Designer
@ Coimbra, Portugal
Who is Pedro ?
The date is 22nd March, 1993. The place is Coimbra. The number of copies, 2. Born to a merchant and an accountant. In the same day, a second copy of me was made, my twin brother.
My best friend.
Since I have memory, I always liked to dedicate a special commitment to the artistic area that is imposed on us throughout our student life. Without, however, ever discarding or devaluing the sciences since they are an indispensable basis for anyone. I love the act of knowing and learning a little about everything, especially if that comes from interacting with other people and other cultures.
So, very soon I knew that the best way to combine those two passions was through the powerful world of design. In so many ways and supports it can teach, promote, show singular perspectives and even make us think about our world like no other form of work. Better design makes our lives easier, simplier and more appealing by providing us with new and better ways to see and do things, even the little daily tasks.
Being able to use the design for this purpose is the main reason why I am a designer and I intend to be for the rest of my life.
What's His Education ?
University of Coimbra
Bachelor’s degree in Multimedia Design
2012 – 2015
University of Coimbra
Master’s degree in Multimedia Design
2015 – 2017
What's His Experience ?
J.Silva – Electrodomésticos
Collaborator
2008 – Present
Centro de Animação Desportiva e Cultural
Multimedia Designer
2015 – Present
MedicineOne, Life Sciences Computing S.A.
UI/UX Designer
2016 – 2017
What's His Skills ?
What he does ?
Graphic Design
Web Design
UI/UX Design
Branding
Infographics
Typography
Editorial
Information Visualization
@


Col one header
Col two header
Col three header
Col one content
Col two content
Col three content
Col one content
Col two content
Col three content
Col one content
Col two content
Col three content
Col one content
Col two content
Col three content


Welcome To Bridal Makeup
Our Makeup Services
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the.
Bridal Makeup
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Bridal Makeup
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Bridal Makeup
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Bridal Makeup
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Bridal Makeup
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Bridal Makeup
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Bridal Makeup
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Bridal Makeup
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Services & Pricing
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy.
Silver Light bride
- bridal makeup $25
- hair style $35
- saree draping $152
- bridal makeup $25
- hair style $35
- saree draping $152
Golden kiss bride
- hd bride makeup $125
- hair styling $300
- faux lash $1000
- brow design $200
- bridal dressing $235
- hair styling $358
Bridal Portfolio
Our Portfolio
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the.
Our Client
Our Testimonial
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the when an printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the when an printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the when an printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.


Call of Duty MW Datamine Reveals Battle Royale Mode Details
by Mike SandersWith the release of Call of Duty Modern Warfare proving to be very popular with fans (both old and new) to the franchise, there is an inescapable truth about all games of this type. Namely, that sooner or later, a battle royale mode is bound to be added.
It’s a trend that, love it or loathe it, few developers are currently brave enough to ignore for too long.
So, why do we mention this? Well, following a Reddit post a user has conducted a huge datamine of the game’s files and believes they have found at least some clues as to what we can expect!
Call of Duty Modern Warfare Battle Royale
Having found some of the map files, the ‘battle royale’ location is believed to have been identified as well as some of the key ‘points of interest’ on it. Digging a little deeper, however, the battle royale mode (based on the map and other information) is shaping up to be one of the most ambitious to date with a rumoured 200 players being able to participate in a single game.
Some of the key mode features have been listed as follows:
- Player Count: 200
- Playlists: Solo (1), Duos (2), and Squads (4)
- End-Game Radar: On
- Infiltration Option: C130
- Pre-Game Lobby Free-for-All: On
- Post-Game Exfiltration: Off
- Max Health: 150
- Last Stand Health: 100 / Revive Health: 30 / Timer: 60s / Revive Time: 7s
- Friendly Fire Punish Limit: 2
- Gulag: On
Will It Be Popular?
This new trend of game mode is certainly not loved by all. As I said earlier, however, this Call of Duty is (perhaps surprisingly) really striking a chord with the community. As such, as and when this arrives, we can see this game mode being hugely popular.
Will it be as good as the standard multiplayer modes? Who can say… I must admit though, as someone who isn’t a particularly huge fan of battle royale games, I am intrigued enough to probably give it more than a few goes.
You can learn more details found in the datamine via the link here!
What do you think? Do you think this introduction would prove popular? – Let us know in the comments!


placeholder
Set a vision for what you ultimately want to achieve with your building. Only you can know what you want, but it’s a good idea to think logically and realistically when deciding what you want to build. A lot of people’s ideas become very extravagant and out of proportion with what they can realistically accomplish. So, it’s important to keep it real. And this is where the next point in the checklist comes in.
You need to begin to thoroughly educate yourself on building with cob or whatever type of building you are going for. Whether you’re building it yourself or having somebody else do it for you, you need to know how everything works and plays together.
Start reading books on cob, natural building, sustainable energy systems, and whatever else interests you for putting together a home. You very well might have to learn a whole new set of skills.
Also try to take hands-on classes and workshops to gain confidence with these new skills. You can find upcoming cob workshops and other sorts of classes below in the ‘Resources' section or by searching online.
Be realistic and conservative in your cost estimates. At least, that’s what I do for my projects because it almost always turns out to consume more time and money than I originally planned for.
The ingredients for cob are cheap, but account for everything that you will need. Foundation materials, roofing materials, windows, doors, electrical, plumbing, tools, machinery, transportation, subcontractors, permits, etc. all cost a lot of money! Don’t lose sight of reality and expect to build your cob home on the cheap just because the walls are made of cob.
Designing a building is an art and a science in itself. The way that you lay out the floor plan for your building will be what you have to live with once the building is built. So, put intelligent thought into your design. You may want to consult with a professional builder or interior designer before going forward with your plans. They can help pick out the faults in your design and offer valuable solutions for you.
The site that you choose for your building can have a large influence on how efficient it is and how it will be preserved over time. There are many aspects to consider for selecting a proper site, which this article won’t be covering, but you need to find a good site before you can put together a detailed design plan. The site can strongly influence the design and function of your building.
placeholder