While designing the navigation for F!ND, it was easy to use my personal preference to decide which navigation features I wanted – after all, I am the target demographic. I performed usability tests on my roommates and friends, people who I knew were a good sample of my target users. I started with the dreaded hamburger menu, and finally made the transition to a bottom tab bar. Read here or here if you still need some convincing to make the switch.
The response was positive. Less clicks + less uncertainty = happier users. (And they said I would never use those 12 math classes I took in undergrad).
But what about a user who knew nothing about the app, nothing about the struggle of living somewhere new or meeting new friends outside of school? How about someone who had grown up with a smartphone glued to his hand? Now that was an opinion I needed.
Read More


US proportion of female directors lags behind Europe
Female directors in widely-held companies (%)
Norway
France
Sweden
Finland
Denmark
Netherlands
Germany
UK
Switzerland
Spain
Ireland
US
0
5
10
15
20
25
30
35
40
45
50
Source: FT analysis of ISS Analytics data


| Apache Struts 2 Documentation > Home > Guides > Core Developers Guide > Application Servers > WebLogic 6.1 |
This document describes why the framework doesn't work "as-is" on Weblogic Server 6.1 and shows how to build an additional JAR that will fix the problems.
The service pack SP4 of Weblogic Server 6.1 was used to test these notes.
The first part of this document describes the technical problems and the theoretical solution.
Weblogic 6.1 was published just prior to the finalization of the Servlet 2.3 specification. The incompatibility is that servlet filters and listeners in Weblogic 6.1 do not work with the 2.3 spec primarily because the servlet context is not retrieved in the same way. This causes virtually all filter initialization operations to fail with an AbstractMethodError exception.
In Servlet 2.3, the servlet context is available from the session object; this is not true for Weblogic Server 6.1. Hence, filters and listeners must be modified to retrieve the servlet context from a different source; this is accomplished by retrieving the servlet context from the FilterConfig passed to the servlet filters during initialzation.
However, the framework code cannot be modifed to do this, because this will break the Servlet 2.3 specification. The goal is to leave the "original" framework unmodified so that it is still Servlet 2.3 compatible, and then to add an additional JAR that "breaks" the frame to work on Weblogic Server 6.1.
The framework has already been modified slightly to make the above effort possible:
Now, in a separate project, the following classes are added and compiled into a separate JAR:
This subclass of RequestLifecycleFilter simply overrides getServletContext() to retrieve the servlet context from the filter config, creates a singleton class, SessionContextSingleton, and assigns the servlet context to the singleton so that the listeners will have the ability to retrieve it.
This subclass of SessionLifecycleListener simply overrides getServletContext() to retrieve the servlet context from the singleton created above.
Although the superclass of this class, FilterDispatcher, is commented out, this subclass retrieves the servlet context in the same way as RequestLifecycleFilterCompatWeblogic61 in case it is ever resurrected. At this time, this class is unnecessary.
A singleton class whose sole purpose is to hold the servlet context so that listener classes have access to it.
In the {{web.xml} file, make the following class name substitutions:
| Old Class Name | New Class Name |
|---|---|
| RequestLifecycleFilter | RequestLifecycleFilterCompatWeblogic61 |
| SessionLifecycleListener | SessionLifecycleListenerCompatWeblogic61 |
| FilterDispatcher | FilterDispatcherCompatWeblogic61 |
Sometimes BEA Weblogic Server doesn't "rebuild" its temporary files. Do the following to force the temporary files to rebuild:


class Equasions
Handles side effects caused by elements changing position or size
class Equasions
Formulas
right: (scope, path) ->
return @['+'](@get(scope, "x", path), @get(scope, "width", path))
bottom: (scope, path) ->
return @['+'](@get(scope, "y", path), @get(scope, "height", path))
center:
x: (scope, path) ->
return @['+'](@get(scope, "x", path), @['/'](@get(scope, "width", path), 2))
y: (scope, path) ->
return @['+'](@get(scope, "y", path), @['/'](@get(scope, "height", path), 2))
module.exports = Equasions


This guide will show you how to convince everyone to join Tavia at the end of "The Walking Dead: 400 Days". In each chapter, there are couple of options which might affect the character’s decision of joining Tavia.
Wyatt
Either Wyatt or Eddie has to check the guy after hitting him, while being chased by an unknown man. You have to stay in the car and leave Eddie behind as this will give Wyatt a reason to join Tavia.
Next, you have to refuse Eddie’s suggestion of playing rock-paper-scissors to decide who checks the body. This will make Eddie go and check the body himself. Or you can accept and play rock-paper-scissors, but you have to win. Losing will cause Eddie to leave Wyatt behind and that is not the option you are looking for.
Vince
When Vince is in the bus, you will have to chop-off either of Justin or Danny’s ankle in order to take the chain off. Shoot Danny’s ankle. Running away with Justin (shooting Danny’s ankle) will teach Vince that shelters are important, while running away with Danny (Shooting Justin’s ankle) will teach him not to trust anyone as this will affect his trust towards Tavia, resulting not going with her.
Russell
At the end of Russell’s chapter, you have two options where you get to decide either joining or leaving Nate. Leaving him will make Russell more likely to join Tavia, but this is largely affected by the way Tavia convinces him.
Shel
Killing or freeing the stranger will not affect Shel’s decision but killing Stephanie will. When you talk to Becca, take the keys and drive the RV away. As Becca mentions, Roman will hunt them down. This will give Shel a reason to join Tavia.
Bonnie
Bonnie is the last one because she will be the first one to join Tavia; no matter what your choices were. You can lie to Leland about Dee’s death or tell him the truth. You can also leave him to die. None of the choices will affect her decision.
Tavia
In Tavia’s chapter, you will have to recruit as much members from the camp as possible. To do so, follow these choices:
-
"I followed the smoke" or "I found your notes"
-
"What would you have me do to convince you?" (This one is important to convince Russell)
-
"You outnumber me"
-
"You might find people you know" (This one is also important to convince Russell)
-
"I give you my word"
Russell becomes nervous when Tavia comes. Regardless of your previous choice regarding Nate’s fate, he won’t join Tavia unless she says "You might find people you know" as this will give him hope to find his family.


Abstract
A home server can be extremely useful for managing your personal data like backing up your files, streaming your music, photos and videos and accessing locally installed services like webmail, webeditor, calendar, notes, contacts, finances and many more.
This is an introductory article for a series of articles for building, deploying, securing, maintaining, troubleshooting and administering your home server or any server in general.
Introduction
A server, either external (hosted on 3rd party providers) or internal (in your home) is a computer dedicated to run an instance of an application (software) capable of accepting requests from the client (your PC, smartphone/tablet, TV etc.) and giving responses accordingly. Servers can run on any computer including dedicated computers, which individually are also often referred to as "the server". Note that in theory, any computerized process that shares a resource to one or more client processes is a server.
Materials and Methods
Before we get started, I would suggest that you should get a member of your family (kids, brother/sister, grandma? ) or a friend involved to the DIY Home Server project because it will be more fun and entertaining than to work alino on the project.
To be able to build a home server we need to understand some terms:
- Hardware
- Network
- Operating System
- Clients
Hardware
The computer that will take the role of a home server could be any spare computer lying around. Unfortunately though this would mean that the this computer will have to be 24/7 powered on, could be loud and the consumption of electricity would make it not viable for the role. That is why I suggest avoid using common computers for home server role but instead buying a credit card-sized single-board computer like:
This type of computers are low on power consumption, silent and generally provide more "value for money". The total return of investment exceeds the one that will be provided by a common computer.
Network
The network is the "glue" that connects our server with the various clients (as mentioned earlier).
The network is consisted of
- Router
- Cables
- IP assignments
Our router is actually a mini internet/dhcp server and its role is to provide Internet connection, IP addresses and data/requests deliverance, among other things through the cables to the the clients and vice versa.
Operating System
There are specialized free (as in beer and freedom of speech) operating systems for the server role that are compatible with the single-board computers that I mentioned earlier. Most popular among them are:
- Ubuntu
- Debian
- Arch Linux
- openSUSE
Personally I prefer Ubuntu because of their predefined development cycle and the 5 years of support on software updates.
You should choose the one that you are comfortable administering as this will be installed on the server for years to come.
Clients
Clients are any devices that connect and exchange information with our home server. The kind of exchange depends on the types of services that the server provides and the capabilities of the device that request those services. A home server usually provides:
- Centralized storage
- Media serving
- Information (calendar, contacts etc.)
- Security monitoring
- P2P file sharing
Results and discussion
Now that we've discussed the core terms of building a home intranet, we should be able to create a draft plan of the parts that we will need to succeed in our project.
I should mention that building a home server not only pays off but it is fun and educative. So stay tuned for the next article either by subscribing to newsletter or following me at social nets.
References
So what do you think? Did I miss something? Is any part unclear? Please leave your comments below


Client
Stored values
Master key
Cache table
| Domain | Salt |
Interaction
Registration
Creates a salt, derives seed, then revocation key and key pair.Send this request to register:
POST https://example.com/frango?subject=?&salt=?&pubkey=?&revocationkeyhash=?
Authentication
Identify ourselves and prove key possession by signing the session id.Send this request to authenticate:
POST https://example.com/frango?subject=?&session=?&signature=?
Revocation
Use revocation key to prove identity and generate a new salt, new revocation key, and new key pair.Send this request to revoke:
POST https://example.com/frango?subject=?&revocationkey=?&newsalt=?&newpubkey=?&newrevocationkeyhash=?
Server
Stored values
Domain
Users
| Subject | Salt | Public key | Revocation key hash |
Sessions
| Id | Subject |


2 Chronicles 32:30
This same Hezekiah also stopped the upper watercourse of Gihon, and brought it straight down to the west side of the city of David. And Hezekiah prospered in all his works.


Table Of Contents
A Simple Paint App(翻訳中)¶
このチュートリアルでは、最初にwidgetを作成する方法を教えます。Kivyアプリケーションをプログラミングする際、あなたが特定の目的ためにカスタム要素で新しいユーザーインターフェースを作成するための最も重要な知識を提供します。
Basic Considerations¶
アプリケーションを作成する前に、自分自身で重要な3つの項目を確かめる必要があります。
アプリケーション・プロセスはどのようなデータですか？
どのようにしてそのデータを視覚的に表現しますか？
ユーザーはどのようにデータと相互作用しますか？
たとえば、非常に単純な線画アプリケーションを記述したいのであれば、ユーザーは指でスクリーンに描画することをたぶん望みます。 それは、ユーザーがアプリケーションと 相互作用 する方法です。その一方で、アプリケーションは後からユーザーの指があった位置を記憶します。そのため、あなたは後からそれらの位置の間に線を描くことができます。つまり、指のあった点はあなたの データ であり、それらの間に描く線は 視覚的な表現 です。
Kivyでは、アプリケーションのユーザーインタフェースはwidgetから構成されています。画面に表示されるすべてが何らかの形でwidgetによって描かれています。しばしば、異なる文脈で書いたコードを再利用したいと思うでしょう。widgetはデータをカプセル化し、そのデータとユーザの対話を定義します。そしてその視覚的な表現を描画します。あなたは、入れ子のwidgetによって、単純なインターフェースから複雑なインタフェースまで、何でも構築することができます。これには、ボタン、スライダーや他の一般的なもの、として構築された多くのwidgetがあります。しかし、多くの場合、Kivyに同胞されているウィジェットの範囲を超えたcustom widget(例えば、医療を視覚化するためのウィジェット)が必要となります。
So keep these three questions in mind when you design your widgets. Try to write them in a minimal and reusable manner (i.e. a widget does exactly what its supposed to do and nothing more. If you need more, write more widgets or compose other widgets of smaller widgets. We try to adhere to the Single Responsibility Principle).
Paint Widget¶
We’re sure one of your childhood dreams has always been creating your own multitouch paint program. Allow us to help you achieve that. In the following sections you will successively learn how to write a program like that using Kivy. Make sure that you have read and understood アプリケーションを作成する. You have? Great! Let’s get started!
Initial Structure¶
Let’s start by writing the very basic code structure that we need. By the way,
all the different pieces of code that are used in this section are also
available in the examples/guide/firstwidget
directory that comes with Kivy,
so you don’t need to copy & paste it all the time.
Here is the basic code skeleton that we will need:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from kivy.app import App
from kivy.uix.widget import Widget
class MyPaintWidget(Widget):
pass
class MyPaintApp(App):
def build(self):
return MyPaintWidget()
if __name__ == '__main__':
MyPaintApp().run()
|
This is actually really simple. Save it as paint.py.

As you can see, instead of using a built-in widget such as a Button (see
アプリケーションを作成する), we are going to write our own widget to do the drawing.
We do that by creating a class that inherits from
Widget
(line 5-6) and although that class does nothing
yet, we can still treat it like a normal Kivy widget (line 11).
The if __name__ ...
construct (line 14) is a Python mechanism that prevents
you from executing the code in the if-statement when importing from the file,
i.e. if you write import paint
, it won’t do something unexpected but
just nicely provide the classes defined in the file.
注釈
You may be wondering why you have to import App and Widget separately,
instead of doing something like from kivy import *
. While shorter,
this would have the disadvantage of polluting your namespace
and make the start of the application potentially much slower.
It can also introduce ambiguity into class and variable naming,
so is generally frowned upon in the Python community. The way we do it is
faster and cleaner.
Adding Behaviour¶
Let’s now add some actual behaviour to the widget, i.e. make it react to user input. Change the code like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from kivy.app import App
from kivy.uix.widget import Widget
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
print(touch)
class MyPaintApp(App):
def build(self):
return MyPaintWidget()
if __name__ == '__main__':
MyPaintApp().run()
|
This is just to show how easy it is to react to user input. When a
MotionEvent
(i.e. a touch, click, etc.) occurs,
we simply print the information about the touch object to the console.
You won’t see anything on the screen, but if you observe the command-line from
which you are running the program, you will see a message for every touch.
This also demonstrates that a widget does not have to
have a visual representation.
Now that’s not really an overwhelming user experience. Let’s add some code that actually draws something into our window:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
with self.canvas:
Color(1, 1, 0)
d = 30.
Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
class MyPaintApp(App):
def build(self):
return MyPaintWidget()
if __name__ == '__main__':
MyPaintApp().run()
|
If you run your code with these modifications, you will see that every time you touch, there will be a small yellow circle drawn where you touched. How does it work?
- Line 9: We use Python’s
with
statement with the widget’sCanvas
object. This is like an area in which the widget can draw things to represent itself on the screen. By using thewith
statement with it, all successive drawing commands that are properly indented will modify this canvas. Thewith
statement also makes sure that after our drawing, internal state can be cleaned up properly.- Line 10: You might have guessed it already: This sets the
Color
for successive drawing operations to yellow (default color format is RGB, so (1, 1, 0) is yellow). This is true until anotherColor
is set. Think of this as dipping your brushes in that color, which you can then use to draw on a canvas until you dip the brushes into another color.- Line 11: We specify the diameter for the circle that we are about to draw. Using a variable for that is preferable since we need to refer to that value multiple times and we don’t want to have to change it in several places if we want the circle bigger or smaller.
- Line 12: To draw a circle, we simply draw an
Ellipse
with equal width and height. Since we want the circle to be drawn where the user touches, we pass the touch’s position to the ellipse. Note that we need to shift the ellipse by-d/2
in the x and y directions (i.e. left and downwards) because the position specifies the bottom left corner of the ellipse’s bounding box, and we want it to be centered around our touch.
That was easy, wasn’t it? It gets better! Update the code to look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse, Line
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
with self.canvas:
Color(1, 1, 0)
d = 30.
Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
touch.ud['line'] = Line(points=(touch.x, touch.y))
def on_touch_move(self, touch):
touch.ud['line'].points += [touch.x, touch.y]
class MyPaintApp(App):
def build(self):
return MyPaintWidget()
if __name__ == '__main__':
MyPaintApp().run()
|
- This is what has changed:
- Line 3: We now not only import the
Ellipse
drawing instruction, but also theLine
drawing instruction. If you look at the documentation forLine
, you will see that it accepts apoints
argument that has to be a list of 2D point coordinates, like(x1, y1, x2, y2, ..., xN, yN)
. - Line 13: This is where it gets interesting.
touch.ud
is a Python dictionary (type <dict>) that allows us to store custom attributes for a touch. - Line 13: We make use of the Line instruction that we imported and
set a Line up for drawing. Since this is done in
on_touch_down
, there will be a new line for every new touch. By creating the line inside thewith
block, the canvas automatically knows about the line and will draw it. We just want to modify the line later, so we store a reference to it in thetouch.ud
dictionary under the arbitrarily chosen but aptly named key ‘line’. We pass the line that we’re creating the initial touch position because that’s where our line will begin. - Lines 15: We add a new method to our widget. This is similar to the
on_touch_down
method, but instead of being called when a new touch occurs, this method is being called when an existing touch (for whichon_touch_down
was already called) moves, i.e. its position changes. Note that this is the sameMotionEvent
object with updated attributes. This is something we found incredibly handy and you will shortly see why. - Line 16: Remember: This is the same touch object that we got in
on_touch_down
, so we can simply access the data we stored away in thetouch.ud
dictionary! To the line we set up for this touch earlier, we now add the current position of the touch as a new point. We know that we need to extend the line because this happens inon_touch_move
, which is only called when the touch has moved, which is exactly why we want to update the line. Storing the line in thetouch.ud
makes it a whole lot easier for us as we don’t have to maintain our own touch-to-line bookkeeping.
- Line 3: We now not only import the
So far so good. This isn’t exactly beautiful yet, though. It looks a bit like spaghetti bolognese. How about giving each touch its own color? Great, let’s do it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | from random import random
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse, Line
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
color = (random(), random(), random())
with self.canvas:
Color(*color)
d = 30.
Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
touch.ud['line'] = Line(points=(touch.x, touch.y))
def on_touch_move(self, touch):
touch.ud['line'].points += [touch.x, touch.y]
class MyPaintApp(App):
def build(self):
return MyPaintWidget()
if __name__ == '__main__':
MyPaintApp().run()
|
Here are the changes:
- Line 1: We import Python’s random() function that will give us random values in the range of [0., 1.).
- Line 10: In this case we simply create a new tuple of 3 random float values that will represent a random RGB color. Since we do this in
on_touch_down
, every new touch will get its own color. Don’t get confused by the use of tuples. We’re just binding the tuple tocolor
for use as a shortcut within this method because we’re lazy.- Line 12: As before, we set the color for the canvas. Only this time we use the random values we generated and feed them to the color class using Python’s tuple unpacking syntax (since the Color class expects three individual color components instead of just 1. If we were to pass the tuple directly, that would be just 1 value being passed, regardless of the fact that the tuple itself contains 3 values).
This looks a lot nicer already! With a lot of skill and patience, you might even be able to create a nice little drawing!
注釈
Since by default the Color
instructions assume RGB mode and we’re feeding a tuple with three
random float values to it, it might very well happen that we end up
with a lot of dark or even black colors if we are unlucky. That would
be bad because by default the background color is dark as well, so you
wouldn’t be able to (easily) see the lines you draw.
There is a nice trick to prevent this: Instead of creating a tuple with
three random values, create a tuple like this: (random(), 1., 1.)
.
Then, when passing it to the color instruction, set the mode to HSV
color space: Color(*color, mode='hsv')
. This way you will have a
smaller number of possible colors, but the colors that you get will
always be equally bright: only the hue changes.
Bonus Points¶
At this point, we could say we are done. The widget does what it’s supposed to do: it traces the touches and draws lines. It even draws circles at the positions where a line begins.
But what if the user wants to start a new drawing? With the current code, the only way to clear the window would be to restart the entire application. Luckily, we can do better. Let us add a Clear button that erases all the lines and circles that have been drawn so far. There are two options now:
- We could either create the button as a child of our widget. That would imply that if you create more than one widget, every widget gets its own button. If you’re not careful, this will also allow users to draw on top of the button, which might not be what you want.
- Or we set up the button only once, initially, in our app class and when it’s pressed we clear the widget.
For our simple example, it doesn’t really matter that much. For larger
applications you should give some thought to who does what in your app.
 We’ll also change to the HSV color space (see preceding note):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | from random import random
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.graphics import Color, Ellipse, Line
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
color = (random(), 1, 1)
with self.canvas:
Color(*color, mode='hsv')
d = 30.
Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
touch.ud['line'] = Line(points=(touch.x, touch.y))
def on_touch_move(self, touch):
touch.ud['line'].points += [touch.x, touch.y]
class MyPaintApp(App):
def build(self):
parent = Widget()
self.painter = MyPaintWidget()
clearbtn = Button(text='Clear')
clearbtn.bind(on_release=self.clear_canvas)
parent.add_widget(self.painter)
parent.add_widget(clearbtn)
return parent
def clear_canvas(self, obj):
self.painter.canvas.clear()
if __name__ == '__main__':
MyPaintApp().run()
|
Here’s what happens:
- Line 4: We added an import statement to be able to use the
Button
class.- Line 25: We create a dummy
Widget()
object as a parent for both our painting widget and the button we’re about to add. This is just a poor-man’s approach to setting up a widget tree hierarchy. We could just as well use a layout or do some other fancy stuff. Again: this widget does absolutely nothing except holding the two widgets we will now add to it as children.- Line 26: We create our
MyPaintWidget()
as usual, only this time we don’t return it directly but bind it to a variable name.- Line 27: We create a button widget. It will have a label on it that displays the text ‘Clear’.
- Line 28: We then bind the button’s on_release event (which is fired when the button is pressed and then released) to the callback function clear_canvas defined on below on Lines 33 & 34.
- Line 29 & 30: We set up the widget hierarchy by making both the painter and the clearbtn children of the dummy parent widget. That means painter and clearbtn are now siblings in the usual computer science tree terminology.
- Line 33 & 34: Up to now, the button did nothing. It was there, visible, and you could press it, but nothing would happen. We change that here: we create a small, throw-away function that is going to be our callback function when the button is pressed. The function just clears the painter’s canvas’ contents, making it black again.
注釈
The Kivy Widget class, by design, is kept simple. There are no general properties such as background color and border color. Instead, the examples and documentation illustrate how to easily handle such simple things yourself, as we have done here, setting the color for the canvas, and drawing the shape. From a simple start, you can move to more elaborate customization. Higher-level built-in widgets, deriving from Widget, such as Button, do have convenience properties such as background_color, but these vary by widget. Use the API docs to see what is offered by a widget, and subclass if you need to add more functionality.
Congratulations! You’ve written your first Kivy widget. Obviously this was just a quick introduction. There is much more to discover. We suggest taking a short break to let what you just learned sink in. Maybe draw some nice pictures to relax? If you feel like you’ve understood everything and are ready for more, we encourage you to read on.


Home
About The Project
The Team
Frequently Appearing Words
A look at which words appear most often in Baleen's news sources
February
March
April
May


A Flask website with a python backend & a postgreSQL database that
allow the user to register and login, track their location and
suggest restaurant recommendations nearby with an API.
It allows the user to add/delete restaurants to lists,
and friend other users to see their food lists. It is deployed with
an AWS CentOS server using nginx as a reverse proxy. Implemented CI/CD on
GitHub, containerized with Docker, and monitored with cAdvisor, Prometheus and Grafana.
Python
Flask
postgreSQL
HTML
CSS
AWS
GitHub Actions
Docker
Prometheus
Grafana
Bootstrap
Github Website Devpost


If you sent a text message to the phone number in the title of the puzzle, cool things would happen!
During the hunt, this puzzle was available by text message. That number is no longer functional, but puzzlers can use the simulator below as a replacement.


=== Test case: lasp_SUITE:contracted_latency_test/1 (click for source code)
=== Config value:
[{watchdog,<0.472.0>},
<EMAIL_ADDRESS>{tc_group_properties,[]},
{tc_group_path,[]},
{data_dir,"/Users/anne-francevanswieten/lasp/_build/test/lib/lasp/test/lasp_SUITE_data/"},
<EMAIL_ADDRESS>=== Current directory is<EMAIL_ADDRESS>=== Started at 2017-05-02 17:28:46
*** User 2017-05-02 17:28:46.577 ***
Beginning case: contracted_latency_test
*** User 2017-05-02 17:28:46.590 ***
17:28:46.590 [info] Configured peer_service_manager partisan_default_peer_service_manager on node 'runner@MacBook-Pro-de-Anne-France'
*** User 2017-05-02 17:28:48.073 ***
17:28:48.073 [info] Enabling membership...
*** User 2017-05-02 17:28:48.075 ***
17:28:48.075 [info] Disabling blocking sync...
*** User 2017-05-02 17:28:48.081 ***
17:28:48.081 [info] Configured peer_service_manager partisan_default_peer_service_manager on node 'node-1@MacBook-Pro-de-Anne-France'
*** User 2017-05-02 17:28:49.678 ***
17:28:49.677 [info] Enabling membership...
*** User 2017-05-02 17:28:49.679 ***
17:28:49.679 [info] Disabling blocking sync...
*** User 2017-05-02 17:28:49.684 ***
17:28:49.684 [info] Configured peer_service_manager partisan_default_peer_service_manager on node 'node-2@MacBook-Pro-de-Anne-France'
*** User 2017-05-02 17:28:51.215 ***
17:28:51.215 [info] Enabling membership...
*** User 2017-05-02 17:28:51.217 ***
17:28:51.217 [info] Disabling blocking sync...
*** User 2017-05-02 17:28:51.223 ***
17:28:51.223 [info] Configured peer_service_manager partisan_default_peer_service_manager on node 'node-3@MacBook-Pro-de-Anne-France'
*** User 2017-05-02 17:28:51.509 ***
Joining node: 'node-3@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 54978
*** User 2017-05-02 17:28:51.513 ***
Joining issued: 'node-3@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 54978
*** User 2017-05-02 17:28:51.513 ***
Joining node: 'node-2@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 54962
*** User 2017-05-02 17:28:51.514 ***
Joining issued: 'node-2@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 54962
*** User 2017-05-02 17:28:51.515 ***
Joining node: 'node-1@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 54949
*** User 2017-05-02 17:28:51.515 ***
Joining issued: 'node-1@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 54949
*** User 2017-05-02 17:28:51.577 ***
Waiting for join to complete with manager: partisan_default_peer_service_manager
*** User 2017-05-02 17:28:51.578 ***
Finished.
*** CT 2017-05-02 17:28:51.591 *** COVER INFO
Adding nodes to cover test: ['runner@MacBook-Pro-de-Anne-France']
*** CT 2017-05-02 17:28:51.598 *** COVER INFO
Successfully added nodes to cover test: []
*** User 2017-05-02 17:28:51.599 ***
Case finished: contracted_latency_test
*** User 2017-05-02 17:28:58.642 ***
17:28:58.642 [info] Application lasp exited with reason: stopped
=== Ended at 2017-05-02 17:28:58
=== successfully completed test case
=== Returned value: ok
Test run history
| Top level test index


This is a command-line calculator application written in Ruby. It converts infix notated expressions to postfix notation in order to perform the mathematic operations in the appropriate order even when provided complex expressions involving parenthesis, addition, subtraction, multiplication, division, and exponents.
Mathematic Notation
Working on this project afforded me the opportunity to learn a lot about mathematic notation. When humans write down mathematic expressions, they often use what’s called infix notation in which the operator is written in between operands and the ‘order of operations’ is obeyed unless parenthesis indicate a different grouping. While humans are great at using those visual tools to group and order various operations, machines have a harder time. Computers love to deal in queues where order is already taken care of. This type of notation is called postfix.
[infix example]
(3-1)/(4+2)
[postfix example]
31-42+/
A machine can evaluate the postfix expression above by moving from left to right and keeping track of all the numbers as it goes. Once it finds the first operator, it uses that operator to evaluate the most recent two numbers, puts the result on the top of the number ‘stack’ and continues evaluating.
3
31
(31-) = 3-1 = 2
24
242
2(42+) = 4+2 = 6
26
(26/) = 2/6 = 0.33
History
Along with being able to evaluate complex expressions. It was important to me that Bloculator be able to keep track of the expressions you ask it to compute as well as the results of those expressions. This allows you to use previous results as part of subsequent expressions and to remember which expressions you previously entered.
One future enhancement that I’d like to see in Bloculator is the ability to export and import calculator histories (currently they only last for the duration of the current calculator instance) both to save calculator actions and to share or re-use results.


Hello there. I'm a Computer Science student at Georgia Tech, with a concentration in the Intelligence and Devices threads (Rogue AIs are more fun when they can control hardware). I'm interested in NLP (especially transformer architectures), reinforcement learning, and robotics.
I am currently working in the NLP and Computational Social Science Lab. In addition, I work in the Automated Algorithm Design Vertically Integrated Project group to optimize algorithms using genetic programming. I'm also a Student Assistant for the Career Services department of the Office of Outreach, Enrollment, and Community in the College of Computing. I have previously worked in the Georgia Tech High-Performace Architecture Lab to adapt conversational and speech-to-text models on IoT devices and robots.
I'm the Executive Officer for The Agency , Georgia Tech's AI club, where I'm working on a project in natural language generation and helping people learn more about the field. Other interests include losing all my money algo-trading, road cycling, and helping find the Ultimate Question of Life, the Universe and Everything .