Blocking Master Example
Blocking Master shows how to create an application for a serial interface using the synchronous API of QSerialPort in a worker thread.
QSerialPort supports two programming alternatives:
- The asynchronous (non-blocking) alternative. Operations are scheduled and performed when the control returns to the Qt event loop. The QSerialPort class emits a signal when the operation is finished. For example, the write() method returns immediately. When the data is sent to the serial port, the QSerialPort class emits the bytesWritten() signal.
- The synchronous (blocking) alternative. In headless and multithreaded applications, the wait method can be called (in this case, waitForReadyRead()) to suspend the calling thread until the operation has completed.
In this example, the synchronous alternative is demonstrated. The Terminal example illustrates the asynchronous alternative.
The purpose of this example is to demonstrate how to simplify your serial programming code without losing the responsiveness of the user interface. The blocking serial programming API often leads to simpler code, but it should only be used in non-GUI threads to keep the user interface responsive.
This application is the master which demonstrates the work paired with the slave application Blocking Slave Example.
The master application initiates the transfer request via the serial port to the slave application and waits for response.
class MasterThread : public QThread { Q_OBJECT public: explicit MasterThread(QObject *parent = nullptr); ~MasterThread(); void transaction(const QString &portName, int waitTimeout, const QString &request); void run() Q_DECL_OVERRIDE; signals: void response(const QString &s); void error(const QString &s); void timeout(const QString &s); private: QString portName; QString request; int waitTimeout; QMutex mutex; QWaitCondition cond; bool quit; };
MasterThread is a QThread subclass that provides API for scheduling requests to the slave. This class provides signals for responding and reporting errors. The transaction() method can be called to start up the new master transaction with the desired request. The result is provided by the response() signal. In case of any issues, the error() or timeout() signal is emitted.
Note, the transaction() method is called in the main thread, but the request is provided in the MasterThread thread. The MasterThread data members are read and written concurrently in different threads, thus the QMutex class is used to synchronize the access.
void MasterThread::transaction(const QString &portName, int waitTimeout, const QString &request) { QMutexLocker locker(&mutex); this->portName = portName; this->waitTimeout = waitTimeout; this->request = request; if (!isRunning()) start(); else cond.wakeOne(); }
The transaction() method stores the serial port name, timeout and request data. The mutex can be locked with QMutexLocker to protect this data. The thread can be started then, unless it is already running. The wakeOne() method is discussed later.
void MasterThread::run() { bool currentPortNameChanged = false; mutex.lock(); QString currentPortName; if (currentPortName != portName) { currentPortName = portName; currentPortNameChanged = true; } int currentWaitTimeout = waitTimeout; QString currentRequest = request; mutex.unlock();
In the run() function, the first is to lock the QMutex object, then fetch the serial port name, timeout and request data by using the member data. Having that done, the QMutex lock is released.
Under no circumstance should the transaction()
method be called simultaneously with a process fetching the data. Note, while the QString class is reentrant, it is not thread-safe. Thereby, it is not recommended to read the serial port name in a request thread, and timeout or request data in another thread. The MasterThread class can only handle one request at a time.
The QSerialPort object is constructed on stack in the run() method before entering the loop:
QSerialPort serial; while (!quit) {
This makes it possible to create an object while running the loop. It also means that all the object methods are executed in the scope of the run() method.
It is checked inside the loop whether or not the serial port name of the current transaction has changed. If this has changed, the serial port is reopened and then reconfigured.
if (currentPortNameChanged) { serial.close(); serial.setPortName(currentPortName); if (!serial.open(QIODevice::ReadWrite)) { emit error(tr("Can't open %1, error code %2") .arg(portName).arg(serial.error())); return; } }
The loop will continue to request data, write to the serial port and wait until all data is transferred.
// write request QByteArray requestData = currentRequest.toLocal8Bit(); serial.write(requestData); if (serial.waitForBytesWritten(waitTimeout)) {
Warning: As for the blocking transfer, the waitForBytesWritten() method should be used after each write method call. This will process all the I/O routines instead of the Qt event loop.
The timeout() signal is emitted if a timeout error occurs when transferring data.
} else { emit timeout(tr("Wait write request timeout %1") .arg(QTime::currentTime().toString())); }
There is a waiting period for response after a successful request, and then it is read again.
// read response if (serial.waitForReadyRead(currentWaitTimeout)) { QByteArray responseData = serial.readAll(); while (serial.waitForReadyRead(10)) responseData += serial.readAll(); QString response(responseData); emit this->response(response);
Warning: As for the blocking alternative, the waitForReadyRead() method should be used before each read() call. This will processes all the I/O routines instead of the Qt event loop.
The timeout() signal is emitted if a timeout error occurs when receiving data.
} else { emit timeout(tr("Wait read response timeout %1") .arg(QTime::currentTime().toString())); }
When a transaction has been completed successfully, the response() signal contains the data received from the slave application:
emit this->response(response);
Afterwards, the thread goes to sleep until the next transaction appears. The thread reads the new data after waking up by using the members and runs the loop from the beginning.
mutex.lock(); cond.wait(&mutex); if (currentPortName != portName) { currentPortName = portName; currentPortNameChanged = true; } else { currentPortNameChanged = false; } currentWaitTimeout = waitTimeout; currentRequest = request; mutex.unlock(); }
Running the Example
To run the example from Qt Creator, open the Welcome mode and select the example from Examples. For more information, visit Building and Running an Example.
Files:
See also Terminal Example and Blocking Slave Example.


{% from 'macros.html' import rankings_macro %} {{ rankings_macro('Season', league_id, None, None, rankings, 'Season Rankings are automatically updated everyday.', 'The code scrapes the "Season Stats" table from the League Standings page') }}


--- title: "" date: 2021-08-01 tags: about image: [support.webp] ---
www.castutor.org is Student Managed for Students improvement. The daily management is run by a team of Springstead High students. Our management team is supported by Great Teachers and Springstead Alumni to ensure our success.


refs to local video files Pink Floyd - Great Gig in the sky Pink Floyd - Another brick in the wall refs to youtube video files Masterpiece 50 million views on youtube Great performance


--- layout: post authors: ["Noam Ross"] title: "Ongoing Learning with User Groups" date: 2014-11-10 time: "13:30:00" tags: ["Teaching", "Community"] ---
For the past two years I've run the UC Davis R User's Group (D-RUG). In this post, I'll (1) outline the structure of D-RUG, (2) summarize some lessons learned, and (3) discuss how such users' groups could act to support and complement SWC's workshops.
D-RUG was created with similar motivations as SWC: to help scientists learn computing skills. Unlike SWC workshops, our model has been "everyone teaches everyone" rather than "instructor-to-learner". I saw that science graduate students at Davis increasingly needed to use R and similar tools in both their coursework and research, and there was a fair bit of knowledge dispersed among students and faculty in the university. But there was little training on programming, and no forum to share our knowledge.
Our users are primarily graduate students and postdocs from across the university, though they're skewed towards ecology and related fields. Most have no training in computer science or programming. They take up R either for coursework or when a specific research task demands it. So they are pretty much in the same place as most SWC Workshop students. We try to maintain low barriers to entry for these students.
Our basic operating principle is maintaining low barriers to entry for users of all skill levels. That means meeting students where they are in terms of their tools and needs, and making it as easy as possible for volunteers to pitch in.
Work sessions: We have weekly, 2-hour co-work sessions where users come to work on their own projects and get help.
Talks and tutorials: About every other week, the first half of our work sessions is dedicated to a presentation. These are mainly tutorials on tools in R. Sometimes they are "show-and-tell" where a user presents an analysis for feedback. Most speakers walk through a script on a large screen, and Q & A takes up half of the time.
A Q & A listserv: We use Google Groups to manage a listserv where people can ask questions, which is especially helpful for our many users who can't attend the weekly sessions. Global fora, like the R mailing lists or Stack Overflow, are great, but in order to scale they need pretty strict rules that are challenging for beginners. Many beginners don't yet know how to frame questions to get good answers. Since our listserv is small-scale, new users can ask open-ended questions and expect responses more helpful than "RTFM."
A website and blog:
Our blog mostly serves as a way to post
materials from our talks,
usually Rmd
scripts or slides.
More recently we have been broadcasting our tutorials with Google Hangouts on Air and posting those videos, as well.
After 2 years, D-RUG has proved a success. A typical meeting brings 5-15 members, usually evenly split between regulars and those who come just when they have questions. Attendance tends to be higher towards the beginning of the term and when we have speakers. A fair number of on-campus (and lots of off-campus users) view the tutorials online. 400 members have signed up for the listserv; 10-20% of these are active posters, and most questions get answered in a day or so. Most importantly, I've seen many users arrive with little or no experience, and go on be our most useful helpers and give some of our best tutorials.
Here a few of the lessons I've learned in running D-RUG:
Users' groups have the potential to be a complementary tool to SWC workshops. We recruited a number of new members at the June SWC Workshop at Davis, and they've been able to practice and build those skills at our work sessions. Users' groups also may be a good forum to stay connected to and follow up with learners.
Beginners need a minimum amount of knowledge to take advantage of D-RUG, which can be provided by SWC workshops. D-RUG doesn't have the resources or structure to teach those beginners from scratch. I sometimes point new users who show up with no experience to an appropriate online self-taught course, and encourage them do the work at our sessions where they can get support. If these members attend a SWC workshop, they will know enough to get started, and to support each other.
The D-RUG model is fairly easy to replicate. Daniel Hocking at the University of New Hampshire has created a similar group. Anyone with the skill level of a typical SWC workshop helper can probably run a users' group, though it does require a certain amount of time and skill at recruiting on-campus.
I'd like to hear from others who have similar or alternative models. How can these groups connect with SWC to build an ongoing community of learners?


So say you are trying out all this interesting new throw
stuff in Swift 2. And
say you’re running an early Beta in which many stdlib functions don’t handle
throw closures yet. Or maybe you’re in the future and dealing with some other
piece of code that you wish could handle a throw closure, but doesn’t. What do
you do?
By now you may be asking “what the heck is a throw closure? Talk sense, man!”
Let’s take a small step back and quickly introduce the new throws
feature.
That’s not the point of this article, though. You should go watch the WWDC
videos. But basically, it’s like this. Say you have a function that might fail.
In Swift 2, you can write it this way:
enum Error: ErrorType { case Negative }
let f: (Int) throws -> String = {
guard $0 >= 0 else { throw Error.Negative }
return "".join(Repeat(count: $0, repeatedValue: "X"))
}
First, the throws
in the signature tells us that this function may throw.
Functions may not throw errors unless they explicitly indicate that they can.
You might think of “throwing errors” as equivalent to “exceptions” in languages
you’re familiar with, but it’s a little different. A throw is really just a
fancy return. A throwing function can return either a type or an ErrorType
.
And “throws” is probably best thought of as somewhat opaque sugar around an
Either type.
That tells us something very important:
A function that throws errors is a different type than one that doesn’t.
I don’t mean that it’s “some other kind of thing.” I mean like Int
is a
different type than String
, and String
is a different type than (Int) ->
String
, (Int) -> String
is a different type than (Int) throws -> String
. In
fact, (Int) -> String
is a subtype of (Int) throws -> String
, which is
pretty awesome and a little subtle, but we’ll get to that in another post.
So what does that mean? Let’s think of a simple case of map today (Swift 2 Beta 1):
print([1,2,3].map(f)) // Cannot invoke 'map' with an argument list of type '((Int) throws -> String)'
What’s going on here? Let’s look at the type signature:
func map<T>(@noescape transform: (Self.Generator.Element) -> T) -> [T]
So transform
is of type (Element) -> T
. We’re passing (Element) throws ->
T
. Remember I said that a non-throwing function is a subtype of a throwing
function. So (Element) throws -> T
is a supertype of what what this function
wants. That’s like passing NSObject to something that wants UIView. You can’t do
that.
So what do we do? Well for map, this is easy. We can just implement our own throwing version:
extension Array {
func map<T>(@noescape transform: (Generator.Element) throws -> T) rethrows -> [T] {
var result: [T] = []
for x in self {
result.append(try transform(x))
}
return result
}
}
And now we can use it:
print(try [1,2,3].map(f))
Notice the use of try
. This is pretty different than how try
is used in
other langauges, and another way that Swift’s error handling doesn’t quite match
“exceptions.” Swift uses try
to remind the programmer about functions that
may throw errors. The compiler doesn’t need try
. It doesn’t create scope, or
mark control flow points, or anything like that. It’s not a function or a
constructor. It’s just a keyword that Swift forces you to include so that you
(and your coworkers) remember what’s going on. When you see try
, you should
think “hey, control could suddenly jump somewhere else from this point.” It
reduces surprise when that happens, and conversely tells you where control
can’t suddenly jump (i.e. everywhere without try
). I think that’s pretty
nice.
You may also notice both throws
and rethrows
in the method signature. I’ll
get to that in a later blog post. Just trust me for now. This code would also
work if you used throws
in both places, but this is the better signature.
And one more “also notice.” Also notice that this is an overload of map. The closures have different types, so the compiler can pick the right one. Nice.
OK, that was a lot of setup, and you could probably figure out on your own how to rewrite map this way. And besides, by beta 2, I’m sure there will be a proper (re)throwing version of map. So why bother? For the next step.
I know how map is implemented. It’s really simple. But what if I didn’t know
how it was implemented? How about some function that I’m not sure I could write
correctly? How about a more obscure function that may not get throwing love
quite so quickly? How about Array.withUnsafeBufferPointer
? Ooohhh….
So here’s our signature:
func withUnsafeBufferPointer<R>(@noescape body: (UnsafeBufferPointer<T>) -> R) -> R
We want to accept a body
that can throw, but we want to pass it to the
existing method, which can’t accept a throwing closure. So what do we do? We go
back to our old friend, Result. Here’s a super-simple Result implementation that
can convert to and from throwing closures:
enum Result<T> {
case Success(T)
case Failure(ErrorType)
func value() throws -> T {
switch self {
case .Success(let value): return value
case .Failure(let err): throw err
}
}
init(@noescape f: () throws -> T) {
do { self = .Success(try f()) }
catch { self = .Failure(error) }
}
}
If you’re familiar with Result or Either, this should be pretty self-evident,
but the key pieces are that result.value()
will unwrap the result into either
a value or a thrown error. And init
will take a throwing closure and convert
it into a Result. With that piece, here’s how we build our method:
extension Array {
func withUnsafeBufferPointer<R>(@noescape body: (UnsafeBufferPointer<T>) throws -> R) throws -> R {
return try self.withUnsafeBufferPointer { buf in
return Result{ try body(buf) }
}.value()
}
}
The closure body
is of type (UnsafeBufferPointer<T>) throws -> R
, which we
can’t pass to withUnsafeBufferPointer
. But our closure is of type
(UnsafeBufferPointer<T>) -> Result<R>
, which is just fine (no throws here,
move along).
Let’s walk through the closure from the inside out.
try body(buf)
. Execute our throwing closure using thebuf
provided to us by the default implementation.Result{...}
. Capture it into a Result enumreturn Result{...}
. Return the Result, not the underlying value.- The whole function nows looks like
return try result.value()
- This either returns the computed value (type
R
), or throws
This method is marked throws
rather than rethrows
because … reasons. (The
final throw doesn’t come directly from body
, but from value()
. That’ll
hopefully make more sense when I explain rethrows
.)
And just for completeness (and because I needed it myself), we can do the same
thing to withUnsafeMutableBufferPointer
, but we need to give the compiler more
type information because of the inout
parameter:
extension Array {
mutating func withUnsafeMutableBufferPointer<R>(@noescape body: (inout UnsafeMutableBufferPointer<T>) throws -> R) throws-> R {
return try self.withUnsafeMutableBufferPointer { (inout buf: UnsafeMutableBufferPointer<T>) in
return Result{try body(&buf)}}.value()
}
}
These particular implementations probably won’t be useful for long. I’m sure the
stdlib team will quickly clean this up (and you probably shouldn’t be using
withUnsafeBufferPointer
very much anyway). But hopefully exploring how this
works can give some insight into Swift’s new error handling system. Result isn’t
dead; it still has interesting use cases like this one. But I expect those use
cases to shrink, and I highly recommend exploring the new error handling and
discover how to build great things with it.


--- layout: post title: apx100 & photoart category: [] tags: - 4k - agfa - antónio capelo - antoniocapelo - apx100 - jupiter8 - olympus - porto - portugal - street - vista - xa2 - zorki status: publish type: post published: true meta: _edit_last: '1' ---
I ran out of B&W rolls and fixer so I wen to the fellas at Câmaras & Companhia and bought some Foma Fixer and a roll of APX100. The film is indeed contrasty, as I read online, but I didn't felt an excessive amount of grain. In fact, I enjoyed this film very much (I've bought 2 more rolls already).
I also received a package with the the Olympus XA2 that I won in an auction for a very low price. Turns out that the low price was due to the camera being broken. Maybe because the shutter seems to be bit by a furious dog. I managed to fix it (for how long? that I don't know), and in the process of realizing that the camera had a problem, I created real photographic art, a mixture of realities, a two-sided capture. That, or I double-exposed the entire roll.

And now, the zorki 4k + Jupiter8 + apx100:
Life is
ikea furniture assembly party
if (empty(glass)==1) then focus
F!
Northern Tourists enjoy the sun in Portugal
Helena's View
it's a trap!
active
praise the sun
dealin'
IT
gardening at the balcony
More rolls to come,
A. Capelo


Gateway
BOT
13-Sep-19 01:51 PM
[dscrdutrum] <gigamesh> why cant I edit after submission @Sri - Lead ?
[dscrdutrum] <Sri - Lead> It goes to blockchain
[dscrdutrum] <Sri - Lead> We can do it like steemit but for now, you cant edit
[dscrdutrum] <gigamesh> can u show me the txid for my Loki review?
[dscrdutrum] <gigamesh> or how can i find it?
[dscrdutrum] <Sri - Lead> Yes, it appears after voting
[dscrdutrum] <Sri - Lead> You can see verify link below post
[dscrdutrum] <gigamesh> voting? pls elaborate
[dscrdutrum] <gigamesh> moderation?
[dscrdutrum] <Sri - Lead> Members are voting on post right
[dscrdutrum] <gigamesh> voting closed? why closed?
(edited)
[dscrdutrum] <Sri - Lead> Voting is open only for 3 days
[dscrdutrum] <Sri - Lead> for every post
[dscrdutrum] <gigamesh> why?
[dscrdutrum] <Sri - Lead> Because the whole system is based on member voting and we cant keep it forever
[dscrdutrum] <Sri - Lead> Based on member voting, rewards and reputation are assigned
[dscrdutrum] <gigamesh> this "voting" is not the same as the moderator check, right?
[dscrdutrum] <gigamesh> if yes why not 30 days?
[dscrdutrum] <Sri - Lead> yes, its member voting
[dscrdutrum] <Sri - Lead> 30 days is too long for people to receive rewards and urs
[dscrdutrum] <Sri - Lead> moderation is different, it only happens for 3 things
[dscrdutrum] <Sri - Lead> copied content, flagged posts and spam
[dscrdutrum] <gigamesh> so i publish... get rewards first 3 days... then what?
[dscrdutrum] <Sri - Lead> nothing
[dscrdutrum] <gigamesh> still rewarded or not?
[dscrdutrum] <gigamesh> ouch
[dscrdutrum] <Sri - Lead> Your post can be viewed forever but you wont receive rewards or reputation for that
[dscrdutrum] <gigamesh> if it goes "viral" after 3 days i get nothing?
[dscrdutrum] <Sri - Lead> Yeah nothing
[dscrdutrum] <gigamesh> u dont think thats harsh?
[dscrdutrum] <Sri - Lead> But you get more followers
[dscrdutrum] <Sri - Lead> It means more votes for your next post
[dscrdutrum] <Sri - Lead> There has to be some deadline and we chose 3 days
[dscrdutrum] <gigamesh> ok i didnt read ToS, do u plan on sharing ad revenue?
[dscrdutrum] <Sri - Lead> Yes
[dscrdutrum] <gigamesh> so i will b rewarded after 3 days? in future?
[dscrdutrum] <gigamesh> for ad revenue?
[dscrdutrum] <Sri - Lead> We need to revisit that
[dscrdutrum] <Sri - Lead> For now we thought 3 days is a good window because most people read it and vote it by then
[dscrdutrum] <gigamesh> how did u arrive at 3 days and r u prepared to change this number thru community vote?
[dscrdutrum] <Sri - Lead> Yes ofcourse
[dscrdutrum] <Sri - Lead> If community thinks 3 days is very less, we can change it
[dscrdutrum] <gigamesh> @Privatoshi - Ambassador im interested in ur input here
[dscrdutrum] <Sri - Lead> But I bet everyone likes 3 days
[dscrdutrum] <gigamesh> 3 is IMHO waaay too little
[dscrdutrum] <Sri - Lead> Reason, being rewards
[dscrdutrum] <gigamesh> but maybe im missing something?
[dscrdutrum] <Sri - Lead> Imagine we have 1000 posts on portal per day
[dscrdutrum] <Sri - Lead> then every one cant vote every post
[dscrdutrum] <Sri - Lead> People are impatient giga
[dscrdutrum] <Sri - Lead> Initially I thought of 15 days
[dscrdutrum] <gigamesh> if u tell them wait and get more money... they will wait
[dscrdutrum] <gigamesh> in my experience
[dscrdutrum] <Sri - Lead> Once we grow, we go for community vote and decide then
[dscrdutrum] <gigamesh> ok, sounds good
[dscrdutrum] <Sri - Lead> 3 days, 7 days, 15 days, 30 days
[dscrdutrum] <Sri - Lead> Let people choose
[dscrdutrum] <gigamesh> i say x10
[dscrdutrum] <Sri - Lead> ahahaha


Oscar Reyes
about
Software Engineer at Blizzard Entertainment
Has been playing StarCraft II since 2013 - Diamond
When asked about anything in life, somehow everything revoles around food
Lives in Austin Texas
Software Engineer at Blizzard Entertainment
Has been playing StarCraft II since 2013 - Diamond
When asked about anything in life, somehow everything revoles around food
Lives in Austin Texas


Hi! My name is Trace Dressen, and I'm a recent graduate from Carnegie Mellon University where I studied Entertainment Technology. Aside from my studies, I've worked in such places as Walt Disney World Resort's Design & Engineering group and Universal Creative. I have always had a great passion for immersive entertainment, whether that means theme parks, video games, or other exciting experiences. Take a look at my portfolio to see some of the games and experiences I've been working on.


Goodnight MH370
Background
The Disappearance
The Search
The Theories
Work Cited
Goodnight Malaysian 370
On March 8 2014, 227 passengers and 12 crew members vanished..
and it wasn't an accident
Where Did They Go?
Click The Button To Continue
This Website Uses Sounds
Ok


Prometheus Consulting Is A Global Recruitment Agency. We at Prometheus Consulting have specialised recruiters working closely with our panel of subject matter experts finding you the right person for the job
Consultants should always keep in mind that client relationship should remain at a professional level. It is sometimes easy for consultants to take on an “employee attitude,” which in many environments can backfire on the consultant and actually create a negative situation for the project.
Consultants should look for ways to adjust their work style to accommodate the schedule, budget and overall requirements of the project. This is particularly true when faced with pressure to maintain high quality within finite time and budget constraints.
Consultants are required to have good judgment when confronted with a problem. We should not jump to conclusions. Consultants should take time to consider the facts and to get feedback from their peers and management before reaching a decision.
Our value proposition defines what differentiates us in the marketplace—what we offer, how we deliver it differently than our competitors, and the way we provide value. It establishes why a company wants to do business with us. We at Prometheus Consulting belive that recruitment can never be ready-to-wear OR one size fits all process. Recognizing that most jobs today are demanding, and there are hardly any simple positions to fill. Talented people are complex in ways that can’t always be identified in a resume or portfolio. At Prometheus we’re experts in knowing and understanding our client objectives. Our Expertise Is The Following But Is Not Limited To
Prometheus Consulting Is A Global Recruitment Agency That Provides Its Clients Best In Class Recruitment & Training Solutions
Simply Fill Up The Form Below And We Would Get Back To You !
410, Vishal Tower, Janakpuri District Centre, Delhi-58 www.prometheusconsulting.in
Copyright © 2017. Prometheus Consulting. Designed by AMIT LOHCHAB


Freephone:
+91<PHONE_NUMBER>
Telephone:
+91<PHONE_NUMBER>
E-mail:
<EMAIL_ADDRESS><EMAIL_ADDRESS>girivishalk@gmail.com


lorem.
Lorem ip.
Lorem ipsum.
Lorem.
Back
Lo.
Lorem ipsum.
Lorem .
Lorem ipsum.
Lorem.
Lorem, ipsum.
Purchase Order
Price
Send Offer
Report as fraudulent
Report this car as fraudulent
Pricing
Weird Demands
Reason
Description
Report


{% extends 'tutor/base.html' %} {% load bootstrap4 %} {% load crispy_forms_tags %} {% bootstrap_css %} {% block content %}
No Jobs? Try updating your account profile with subjects you would be interested in tutoring.


Package com.google.api
Interface MetricDescriptorOrBuilder
- All Superinterfaces:
com.google.protobuf.MessageLiteOrBuilder
,com.google.protobuf.MessageOrBuilder
- All Known Implementing Classes:
MetricDescriptor
,MetricDescriptor.Builder
public interface MetricDescriptorOrBuilder
extends com.google.protobuf.MessageOrBuilder
-
Method Summary
Modifier and TypeMethodDescriptionA detailed description of the metric, which can be used in documentation.com.google.protobuf.ByteString
A detailed description of the metric, which can be used in documentation.A concise name for the metric, which can be displayed in user interfaces.com.google.protobuf.ByteString
A concise name for the metric, which can be displayed in user interfaces.getLabels
(int index) The set of labels that can be used to describe a specific instance of this metric type.int
The set of labels that can be used to describe a specific instance of this metric type.The set of labels that can be used to describe a specific instance of this metric type.getLabelsOrBuilder
(int index) The set of labels that can be used to describe a specific instance of this metric type.List<? extends LabelDescriptorOrBuilder>
The set of labels that can be used to describe a specific instance of this metric type.Optional.int
Optional.Optional.Optional.Whether the metric records instantaneous values, changes to a value, etc.int
Whether the metric records instantaneous values, changes to a value, etc.getMonitoredResourceTypes
(int index) Read-only.com.google.protobuf.ByteString
getMonitoredResourceTypesBytes
(int index) Read-only.int
Read-only.Read-only.getName()
The resource name of the metric descriptor.com.google.protobuf.ByteString
The resource name of the metric descriptor.getType()
The metric type, including its DNS name prefix.com.google.protobuf.ByteString
The metric type, including its DNS name prefix.getUnit()
The units in which the metric value is reported.com.google.protobuf.ByteString
The units in which the metric value is reported.Whether the measurement is an integer, a floating-point number, etc.int
Whether the measurement is an integer, a floating-point number, etc.boolean
Optional.Methods inherited from interface com.google.protobuf.MessageLiteOrBuilder
isInitialized
Methods inherited from interface com.google.protobuf.MessageOrBuilder
findInitializationErrors, getAllFields, getDefaultInstanceForType, getDescriptorForType, getField, getInitializationErrorString, getOneofFieldDescriptor, getRepeatedField, getRepeatedFieldCount, getUnknownFields, hasField, hasOneof
-
Method Details
-
getName
String getName()The resource name of the metric descriptor.
string name = 1;
- Returns:
- The name.
-
getNameBytes
com.google.protobuf.ByteString getNameBytes()The resource name of the metric descriptor.
string name = 1;
- Returns:
- The bytes for name.
-
getType
String getType()The metric type, including its DNS name prefix. The type is not URL-encoded. All user-defined metric types have the DNS name `custom.googleapis.com` or `external.googleapis.com`. Metric types should use a natural hierarchical grouping. For example: "custom.googleapis.com/invoice/paid/amount" "external.googleapis.com/prometheus/up" "appengine.googleapis.com/http/server/response_latencies"
string type = 8;
- Returns:
- The type.
-
getTypeBytes
com.google.protobuf.ByteString getTypeBytes()The metric type, including its DNS name prefix. The type is not URL-encoded. All user-defined metric types have the DNS name `custom.googleapis.com` or `external.googleapis.com`. Metric types should use a natural hierarchical grouping. For example: "custom.googleapis.com/invoice/paid/amount" "external.googleapis.com/prometheus/up" "appengine.googleapis.com/http/server/response_latencies"
string type = 8;
- Returns:
- The bytes for type.
-
getLabelsList
List<LabelDescriptor> getLabelsList()The set of labels that can be used to describe a specific instance of this metric type. For example, the `appengine.googleapis.com/http/server/response_latencies` metric type has a label for the HTTP response code, `response_code`, so you can look at latencies for successful responses or just for responses that failed.
repeated .google.api.LabelDescriptor labels = 2;
-
getLabels
The set of labels that can be used to describe a specific instance of this metric type. For example, the `appengine.googleapis.com/http/server/response_latencies` metric type has a label for the HTTP response code, `response_code`, so you can look at latencies for successful responses or just for responses that failed.
repeated .google.api.LabelDescriptor labels = 2;
-
getLabelsCount
int getLabelsCount()The set of labels that can be used to describe a specific instance of this metric type. For example, the `appengine.googleapis.com/http/server/response_latencies` metric type has a label for the HTTP response code, `response_code`, so you can look at latencies for successful responses or just for responses that failed.
repeated .google.api.LabelDescriptor labels = 2;
-
getLabelsOrBuilderList
List<? extends LabelDescriptorOrBuilder> getLabelsOrBuilderList()The set of labels that can be used to describe a specific instance of this metric type. For example, the `appengine.googleapis.com/http/server/response_latencies` metric type has a label for the HTTP response code, `response_code`, so you can look at latencies for successful responses or just for responses that failed.
repeated .google.api.LabelDescriptor labels = 2;
-
getLabelsOrBuilder
The set of labels that can be used to describe a specific instance of this metric type. For example, the `appengine.googleapis.com/http/server/response_latencies` metric type has a label for the HTTP response code, `response_code`, so you can look at latencies for successful responses or just for responses that failed.
repeated .google.api.LabelDescriptor labels = 2;
-
getMetricKindValue
int getMetricKindValue()Whether the metric records instantaneous values, changes to a value, etc. Some combinations of `metric_kind` and `value_type` might not be supported.
.google.api.MetricDescriptor.MetricKind metric_kind = 3;
- Returns:
- The enum numeric value on the wire for metricKind.
-
getMetricKind
MetricDescriptor.MetricKind getMetricKind()Whether the metric records instantaneous values, changes to a value, etc. Some combinations of `metric_kind` and `value_type` might not be supported.
.google.api.MetricDescriptor.MetricKind metric_kind = 3;
- Returns:
- The metricKind.
-
getValueTypeValue
int getValueTypeValue()Whether the measurement is an integer, a floating-point number, etc. Some combinations of `metric_kind` and `value_type` might not be supported.
.google.api.MetricDescriptor.ValueType value_type = 4;
- Returns:
- The enum numeric value on the wire for valueType.
-
getValueType
MetricDescriptor.ValueType getValueType()Whether the measurement is an integer, a floating-point number, etc. Some combinations of `metric_kind` and `value_type` might not be supported.
.google.api.MetricDescriptor.ValueType value_type = 4;
- Returns:
- The valueType.
-
getUnit
String getUnit()The units in which the metric value is reported. It is only applicable if the `value_type` is `INT64`, `DOUBLE`, or `DISTRIBUTION`. The `unit` defines the representation of the stored metric values. Different systems might scale the values to be more easily displayed (so a value of `0.02kBy` _might_ be displayed as `20By`, and a value of `3523kBy` _might_ be displayed as `3.5MBy`). However, if the `unit` is `kBy`, then the value of the metric is always in thousands of bytes, no matter how it might be displayed. If you want a custom metric to record the exact number of CPU-seconds used by a job, you can create an `INT64 CUMULATIVE` metric whose `unit` is `s{CPU}` (or equivalently `1s{CPU}` or just `s`). If the job uses 12,005 CPU-seconds, then the value is written as `12005`. Alternatively, if you want a custom metric to record data in a more granular way, you can create a `DOUBLE CUMULATIVE` metric whose `unit` is `ks{CPU}`, and then write the value `12.005` (which is `12005/1000`), or use `Kis{CPU}` and write `11.723` (which is `12005/1024`). The supported units are a subset of [The Unified Code for Units of Measure](https://unitsofmeasure.org/ucum.html) standard: **Basic units (UNIT)** * `bit` bit * `By` byte * `s` second * `min` minute * `h` hour * `d` day * `1` dimensionless **Prefixes (PREFIX)** * `k` kilo (10^3) * `M` mega (10^6) * `G` giga (10^9) * `T` tera (10^12) * `P` peta (10^15) * `E` exa (10^18) * `Z` zetta (10^21) * `Y` yotta (10^24) * `m` milli (10^-3) * `u` micro (10^-6) * `n` nano (10^-9) * `p` pico (10^-12) * `f` femto (10^-15) * `a` atto (10^-18) * `z` zepto (10^-21) * `y` yocto (10^-24) * `Ki` kibi (2^10) * `Mi` mebi (2^20) * `Gi` gibi (2^30) * `Ti` tebi (2^40) * `Pi` pebi (2^50) **Grammar** The grammar also includes these connectors: * `/` division or ratio (as an infix operator). For examples, `kBy/{email}` or `MiBy/10ms` (although you should almost never have `/s` in a metric `unit`; rates should always be computed at query time from the underlying cumulative or delta value). * `.` multiplication or composition (as an infix operator). For examples, `GBy.d` or `k{watt}.h`. The grammar for a unit is as follows: Expression = Component { "." Component } { "/" Component } ; Component = ( [ PREFIX ] UNIT | "%" ) [ Annotation ] | Annotation | "1" ; Annotation = "{" NAME "}" ; Notes: * `Annotation` is just a comment if it follows a `UNIT`. If the annotation is used alone, then the unit is equivalent to `1`. For examples, `{request}/s == 1/s`, `By{transmitted}/s == By/s`. * `NAME` is a sequence of non-blank printable ASCII characters not containing `{` or `}`. * `1` represents a unitary [dimensionless unit](https://en.wikipedia.org/wiki/Dimensionless_quantity) of 1, such as in `1/s`. It is typically used when none of the basic units are appropriate. For example, "new users per day" can be represented as `1/d` or `{new-users}/d` (and a metric value `5` would mean "5 new users). Alternatively, "thousands of page views per day" would be represented as `1000/d` or `k1/d` or `k{page_views}/d` (and a metric value of `5.3` would mean "5300 page views per day"). * `%` represents dimensionless value of 1/100, and annotates values giving a percentage (so the metric values are typically in the range of 0..100, and a metric value `3` means "3 percent"). * `10^2.%` indicates a metric contains a ratio, typically in the range 0..1, that will be multiplied by 100 and displayed as a percentage (so a metric value `0.03` means "3 percent").
string unit = 5;
- Returns:
- The unit.
-
getUnitBytes
com.google.protobuf.ByteString getUnitBytes()The units in which the metric value is reported. It is only applicable if the `value_type` is `INT64`, `DOUBLE`, or `DISTRIBUTION`. The `unit` defines the representation of the stored metric values. Different systems might scale the values to be more easily displayed (so a value of `0.02kBy` _might_ be displayed as `20By`, and a value of `3523kBy` _might_ be displayed as `3.5MBy`). However, if the `unit` is `kBy`, then the value of the metric is always in thousands of bytes, no matter how it might be displayed. If you want a custom metric to record the exact number of CPU-seconds used by a job, you can create an `INT64 CUMULATIVE` metric whose `unit` is `s{CPU}` (or equivalently `1s{CPU}` or just `s`). If the job uses 12,005 CPU-seconds, then the value is written as `12005`. Alternatively, if you want a custom metric to record data in a more granular way, you can create a `DOUBLE CUMULATIVE` metric whose `unit` is `ks{CPU}`, and then write the value `12.005` (which is `12005/1000`), or use `Kis{CPU}` and write `11.723` (which is `12005/1024`). The supported units are a subset of [The Unified Code for Units of Measure](https://unitsofmeasure.org/ucum.html) standard: **Basic units (UNIT)** * `bit` bit * `By` byte * `s` second * `min` minute * `h` hour * `d` day * `1` dimensionless **Prefixes (PREFIX)** * `k` kilo (10^3) * `M` mega (10^6) * `G` giga (10^9) * `T` tera (10^12) * `P` peta (10^15) * `E` exa (10^18) * `Z` zetta (10^21) * `Y` yotta (10^24) * `m` milli (10^-3) * `u` micro (10^-6) * `n` nano (10^-9) * `p` pico (10^-12) * `f` femto (10^-15) * `a` atto (10^-18) * `z` zepto (10^-21) * `y` yocto (10^-24) * `Ki` kibi (2^10) * `Mi` mebi (2^20) * `Gi` gibi (2^30) * `Ti` tebi (2^40) * `Pi` pebi (2^50) **Grammar** The grammar also includes these connectors: * `/` division or ratio (as an infix operator). For examples, `kBy/{email}` or `MiBy/10ms` (although you should almost never have `/s` in a metric `unit`; rates should always be computed at query time from the underlying cumulative or delta value). * `.` multiplication or composition (as an infix operator). For examples, `GBy.d` or `k{watt}.h`. The grammar for a unit is as follows: Expression = Component { "." Component } { "/" Component } ; Component = ( [ PREFIX ] UNIT | "%" ) [ Annotation ] | Annotation | "1" ; Annotation = "{" NAME "}" ; Notes: * `Annotation` is just a comment if it follows a `UNIT`. If the annotation is used alone, then the unit is equivalent to `1`. For examples, `{request}/s == 1/s`, `By{transmitted}/s == By/s`. * `NAME` is a sequence of non-blank printable ASCII characters not containing `{` or `}`. * `1` represents a unitary [dimensionless unit](https://en.wikipedia.org/wiki/Dimensionless_quantity) of 1, such as in `1/s`. It is typically used when none of the basic units are appropriate. For example, "new users per day" can be represented as `1/d` or `{new-users}/d` (and a metric value `5` would mean "5 new users). Alternatively, "thousands of page views per day" would be represented as `1000/d` or `k1/d` or `k{page_views}/d` (and a metric value of `5.3` would mean "5300 page views per day"). * `%` represents dimensionless value of 1/100, and annotates values giving a percentage (so the metric values are typically in the range of 0..100, and a metric value `3` means "3 percent"). * `10^2.%` indicates a metric contains a ratio, typically in the range 0..1, that will be multiplied by 100 and displayed as a percentage (so a metric value `0.03` means "3 percent").
string unit = 5;
- Returns:
- The bytes for unit.
-
getDescription
String getDescription()A detailed description of the metric, which can be used in documentation.
string description = 6;
- Returns:
- The description.
-
getDescriptionBytes
com.google.protobuf.ByteString getDescriptionBytes()A detailed description of the metric, which can be used in documentation.
string description = 6;
- Returns:
- The bytes for description.
-
getDisplayName
String getDisplayName()A concise name for the metric, which can be displayed in user interfaces. Use sentence case without an ending period, for example "Request count". This field is optional but it is recommended to be set for any metrics associated with user-visible concepts, such as Quota.
string display_name = 7;
- Returns:
- The displayName.
-
getDisplayNameBytes
com.google.protobuf.ByteString getDisplayNameBytes()A concise name for the metric, which can be displayed in user interfaces. Use sentence case without an ending period, for example "Request count". This field is optional but it is recommended to be set for any metrics associated with user-visible concepts, such as Quota.
string display_name = 7;
- Returns:
- The bytes for displayName.
-
hasMetadata
boolean hasMetadata()Optional. Metadata which can be used to guide usage of the metric.
.google.api.MetricDescriptor.MetricDescriptorMetadata metadata = 10;
- Returns:
- Whether the metadata field is set.
-
getMetadata
MetricDescriptor.MetricDescriptorMetadata getMetadata()Optional. Metadata which can be used to guide usage of the metric.
.google.api.MetricDescriptor.MetricDescriptorMetadata metadata = 10;
- Returns:
- The metadata.
-
getMetadataOrBuilder
MetricDescriptor.MetricDescriptorMetadataOrBuilder getMetadataOrBuilder()Optional. Metadata which can be used to guide usage of the metric.
.google.api.MetricDescriptor.MetricDescriptorMetadata metadata = 10;
-
getLaunchStageValue
int getLaunchStageValue()Optional. The launch stage of the metric definition.
.google.api.LaunchStage launch_stage = 12;
- Returns:
- The enum numeric value on the wire for launchStage.
-
getLaunchStage
LaunchStage getLaunchStage()Optional. The launch stage of the metric definition.
.google.api.LaunchStage launch_stage = 12;
- Returns:
- The launchStage.
-
getMonitoredResourceTypesList
Read-only. If present, then a [time series][google.monitoring.v3.TimeSeries], which is identified partially by a metric type and a [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor], that is associated with this metric type can only be associated with one of the monitored resource types listed here.
repeated string monitored_resource_types = 13;
- Returns:
- A list containing the monitoredResourceTypes.
-
getMonitoredResourceTypesCount
int getMonitoredResourceTypesCount()Read-only. If present, then a [time series][google.monitoring.v3.TimeSeries], which is identified partially by a metric type and a [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor], that is associated with this metric type can only be associated with one of the monitored resource types listed here.
repeated string monitored_resource_types = 13;
- Returns:
- The count of monitoredResourceTypes.
-
getMonitoredResourceTypes
Read-only. If present, then a [time series][google.monitoring.v3.TimeSeries], which is identified partially by a metric type and a [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor], that is associated with this metric type can only be associated with one of the monitored resource types listed here.
repeated string monitored_resource_types = 13;
- Parameters:
index
- The index of the element to return.- Returns:
- The monitoredResourceTypes at the given index.
-
getMonitoredResourceTypesBytes
com.google.protobuf.ByteString getMonitoredResourceTypesBytes(int index) Read-only. If present, then a [time series][google.monitoring.v3.TimeSeries], which is identified partially by a metric type and a [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor], that is associated with this metric type can only be associated with one of the monitored resource types listed here.
repeated string monitored_resource_types = 13;
- Parameters:
index
- The index of the value to return.- Returns:
- The bytes of the monitoredResourceTypes at the given index.
-


{% load staticfiles %}
With this easy to use tool, you can easily find out if any address is located inside of a hubzone! If you don't have a lot to find out, try using our single search. If you have a lot, try our Multi-Search or file drop!


# Weekly Programmer - Week 3 ## Making Change From [Weekly Programmer Challenges](./index.html) ## Description You own a nice tiny mini-market that sells candies to children. You need to know what change to give back to those little cute creatures and it happens you don't know basic math because when you were a child you were always eating candies and did not study very well. So you need some help from a little tool that tell you if you can. ## Challenge Description Write a program that calculates change and outputs the minimum amount of coins needed to produce the required change. Your program should receive as input the values of coins available to use, and the value of change needed as a decimal amount of dollars. If the exact amount is not satisfiable your program should round up to the next highest satisfiable value and output the coins needed for that. Your program should output the coins required to give the correct change. For example: Input: ```text .5 .25 .1 .05 .01 1.24 ``` Output: ```text .5 .5 .1 .1 .01 .01 .01 .01 ``` ## Challenge Inputs ```text 1 .5 .25 .1 .05 .01 4.99 ``` ```text 1 .5 .25 .1 .05 4.89 ``` ```text 1 .5 .25 .1 .05 .01 .66 ``` ```text 5 2 .5 .25 .1 .05 16.01 ``` ```text 1 .5 .25 .1 .3 ``` ## Example Solution ```javascript const makeChange = (target, coins) => { const factor = Math.pow(10, coins.concat(target) .map(x => /\d+(.(\d*))?/.exec(x)[2] || '') .reduce((a, v) => Math.max(v.length, a), 0)); target = Math.round(target * factor); coins = coins.map(x => Math.round(x * factor)); const values = [0]; let i = 0; for (; i < target; i++) { if (i in values) { coins.forEach(coin => { const next = i + coin; if (!(next in values)) { values[next] = coin } }); } } i = target; while (!(i in values)) { i++; } const solution = []; for (; i > 0; i -= values[i]) { solution[i - 1] = values[i]; } return solution.filter(value => value) .map(coin => coin / factor) .sort((a, b) => b - a) }; console.log(makeChange(1.24, [.5, .25, .1, .05, .01,])); ``` ## Solution Explanation This solution applies a breadcrumb strategy for backtracking. First the values of the coins are scaled up to make the values integer and the scaling factor is saved. This allows the algorithm to work only with integers and scale the result back down to decimals at the end. Next a list of reachable coin values is created. Starting at `0` the available coins are added to that sum and their numeric value is stored at the new sum. If the new sum already has a value stored it is preserved as that means a shorter path to the reachable value was already produced. This process is repeated for every reachable value up to the target amount of change. This storage allows the single list of values to contain not only which values are reachable but starting from any given value there is a trail of breadcrumbs leading back to `0` which gives the shortest path, and thus the smallest number of coins needed to produce the needed sum. Once this list is generated the smallest reachable value that is at least as great as the needed sum is chosen and the trail of breadcrumbs is walked back to `0`. This list of coins is then sorted largest to smallest and reduced by the previously stored factor to give the result in the original input units.


TITLE
Home
About Me
Research
Photography
Blog
page 2
Being Interacting
First
couple
of
things
First
couple
of
things
First
couple
of
things
n
H
2
0
Styles and COlours
Hello
Something
there is stuff
there is stuff 2
ings
To
Say
ings
To
Say
List of numbers
num1
num2
num3
one
two
three


This is a heading
This is a paragraph, followed by a list of bullet points:
HTML
CSS
JavaScript
Modify!


Story About Us
Being a researcher or a student may face numerous pressures when it comes to the end. Combine studies with work, researching and write thesis sitting at libraries make you frustrated. You may need help under that circumstances. We are here to help you.
We “Virtual Researcher”, your one-stop virtual research assistant, where you can expect outstanding results in no time through our exceptional and efficient virtual research services. If you searching for assistant to do your research or thesis and get it done with high quality output, there is no need to look anyone because you have come to the right place.
We are a qualitative and quantitative virtual research assisting and thesis writing assisting service for so many years with wide range of experience.
Researching and thesis writing being not that easy. Many of you may started well but then lack of experience and not enough time can be a huge disadvantage for your framework and research methodology. But not anymore…
Here We are for you!!
We employ well-educated, qualified academic staff and researchers for your research or thesis paper. You are in the hands of best experts and you will get the most competent help and friendly service. Set your worries away about the quality of the work and enjoy life while we do it for you!
Select the service type that you need to get done and contact our support. We will be happy to help you out of a critical academic situation. You will never find a similarly committed and experts elsewhere...


This page is intended to describe the process of plugin-compat-tester tooling allowing to generate compatibility matrix for plugins against jenkins core.
Process
Process of the plugin-compat-tester is as follow :
- Retrieve update-center.json file
- Extracting jenkins core latest released version. This will be used as JENKINS_VERSION. This version is overridable by passing parameter to plugin-compat-tester.
- Extracting last released version hpi url for every plugins. Iterating over these urls and :
- Extracting pom.xml for current plugin, located in META-INF/maven/... in the hpi file
- Locating /parent/scm/connectionUrl for the currently released plugin
- Checkouting plugin sources from this url (thanks to maven-scm-api )
- Hacking checkouted pom.xml by replacing <parent> section with updated GAV. Version used is JENKINS_VERSION. groupId & artifactId are the standard jenkins ones (org.jenkins-ci.plugins:plugin), these groupId/artifactId could be overriden by specifying other groupId/artifactId ... the hudson ones for example
- After pom.xml is hacked, run "mvn test" and gather if everything compiled successfully AND if all tests passed successfully.
- Save this information in a XML report file storing the JENKINS_VERSION used
We could then use the generated XML and generate some sort of matrix with jenkins version on columns and plugins on rows. Cells will contain icons for compilation and tests.
Devoxx '11 BOF Presentation about Plugin Compat Tester is available here.
Plugin compatibility tester GAE application is available here.
Jenkins CI build job to provide data to GAE application is available here : launch the parameterized build if you have sufficient rights, it will be self documented on parameters pages (disabled since Feb 2013).


Usergroups¶
Usergroups are as the name suggests a group of users formed using the id’s with which they are registered in BuildingDepot. Usergroups when combined with SensorGroups help in bringing about the Access Control functions that BuildingDepot provides.
Create UserGroup¶
This request creates a new UserGroup with the name and description as specified by the user.
-
POST
/api/user_group
¶ Parameters: - name (string) – Name of UserGroup
- description (optional) (string) – Descrption for UserGroup
Returns: - success (string) – Returns ‘True’ if data is posted succesfully otherwise ‘False’
- error (string) – An additional value that will be present only if the request fails specifying the cause for failure
Status Codes: - 200 OK – Success
- 401 Unauthorized – Unauthorized Credentials (See HTTP 401)
Example request:
POST /api/user_group
{
"name": "Test User Group",
"description": "Description for User Group"
}
Example response (for succcess):
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": "True"
}
Example response (for failure):
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": "False",
"error": "No Name"
}
Add users to UserGroup¶
This request adds the users specified in the request to the usergroup
Note: The list of user id’s sent in this request will overwrite the previous list
-
POST
/api/user_group/<name>/users
¶ Parameters: - name (string) – Name of UserGroup
JSON Parameters: - data (list) – List of user ID’s
Returns: - success (string) – Returns ‘True’ if data is posted succesfully otherwise ‘False’
- error (string) – An additional value that will be present only if the request fails specifying the cause for failure
Status Codes: - 200 OK – Success
- 401 Unauthorized – Unauthorized Credentials (See HTTP 401)
Example request:
POST /api/user_group/Test/users
Accept: application/json; charset=utf-8
{
"data":[
<EMAIL_ADDRESS><EMAIL_ADDRESS>]
}
Example response (for succcess):
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": "True"
}
Example response (for failure):
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": "False",
"error": "One or more users not registered"
}
Get list of users in UserGroup¶
This request retrieves the list of users that are in the specified UserGroup
-
GET
/api/user_group/<name>/users
¶ Parameters: - name (string) – Name of user group (compulsory)
Returns: - users (list) – Contains the list of users in this UserGroup
Status Codes: - 200 OK – Success
- 401 Unauthorized – Unauthorized Credentials (See HTTP 401)
Example request:
GET /api/user_group/Test/users
Accept: application/json; charset=utf-8
Example response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"users": [
<EMAIL_ADDRESS><EMAIL_ADDRESS>]
}


Design Patterns are blueprints that help to handle some software design problems.
Refer to this link for a detailed catalog of design patterns.This is similar to the Facade design pattern where we have a wrapper to abstract out the internal processes.
For example, let's say we have a function called addItemList() that runs the following process sequentially:
1. starts a spinner
2. sends HTTP request to backend, receives
3. stops spinner upon receiving of HTTP response
Then, we can use a FacadeService to abstract the processes.
// IN facade.service.ts
private _itemListConfigurationService: ItemListConfigurationService;
public get itemListConfigurationService(): ItemListConfigurationService{
if (!this._itemListConfigurationService){
this._itemListConfigurationService = this.injector.get(ItemListConfigurationService);
}
return this._itemListConfigurationService;
}
private itemListConfigurationHandler = {
next: statusText => {
this.getItemList$().subscribe(
(statusText) => {
this.energyShareFacadeService.stopSpinner();
this.energyShareFacadeService.openSnackBar(statusText);
}
);
},
error: error => {
this.energyShareFacadeService.stopSpinner();
this.energyShareFacadeService.promptError(error);
}
};
getItemList$(): Observable<any> {
return this.itemConfigurationService.getItemList$();
}
addItem(itemObject: IItemObject) {
this.energyShareFacadeService.startSpinner();
this.itemConfigurationService.addItem(itemObject).subscribe(this.itemListConfigurationHandler);
}
deleteItem(itemUUID: string) {
this.energyShareFacadeService.startSpinner();
this.itemListConfigurationService.deleteItem(itemUUID).subscribe(this.itemListConfigurationHandler);
}
// IN item-list-configuration.component.ts
ngOnInit(): void {
this.shareFacadeService.startInitSpinner();
this.facadeService.getItemList$().subscribe(
() => {
this.shareFacadeService.stopInitSpinner();
}
);
}
addItem(itemName: string): void {
const itemObj = {
name: itemName
uuid: null
}
this.facadeService.addItem(itemObj);
}
deleteItem(itemUUID: string): void {
this.facadeService.addItem(itemUUID);
}
Using facade pattern or an abstraction layer also helps us in practising Singleton pattern.
For example, if the itemListConfigurationService is declared in providers of more than one modules, then it will have multiple instances.
If Subject Subscription is used, then only the subscription of the same instance will be notified about the changes.
You may refer to this Github issue regarding this problemFor more detailed explanation about High-level Abstraction Layer practice, you may refer to this link
This architectural pattern divides components into smart components and dumb components.
Dumb Components are also known as Presentational Components, as they only responsible for UI presentation as well as passing user's event to smart components.
On the other hand, Smart Components are the components that pass data to and react to events from dumb components. The business logics and communication with services are handled by smart components.
Example
// IN header.component.html (Dumb Component HTML)

 { {headerTitle}}

{ {subHeaderTitle}}

<ng-content select=[additional-buttons]></ng-content>

// IN header.component.ts (Dumb Component)
@Component({
selector: 'my-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class EnergyHeaderComponent {
@Input() headerTitle: string;
@Input() subHeaderTitle: string;
}
// IN item-list-configuration.component.html (Smart Component HTML)

<my-header class="flexContentSize" [headerTitle]="'Configuration'" [subHeaderTitle]="'Item List Configuration'">
</my-header>

<configuration-element-here></configuration-element-here>

For more detailed explanation about Smart & Dumb Components, you may refer to this link


Food & Drink
Quiche
I made quiche for breakfast yesterday. I'd baked a ham the night before, and there were leftovers. I also had plenty of eggs in the fridge, as well as a decent supply of pastry flour. "Damn, this is the best quiche I've ever eaten" -- my husband I've never been...
Food in a Pandemic
I'm a little disappointed that I haven't kept this site up-to-date during this pandemic. So much of my food habits have changed, and it's a pity that I haven't documented it all. My location has changed too — Kin and I moved from Seattle to Oakland a month ago. And...
Flavortown
The past month has been a whirlwind of "fine dining" and "oh my god, what did I just put in my mouth." I ate, for the first time, at a Michelin star restaurant: Hugo's in Berlin. It was exquisite. I ate at Roy Choi's new restaurant, Best Friend, in Las...
Pie
I never really liked pie, mostly because I think the British hide horrible things in theirs, pretending like a nice flaky crust makes up for the fact that the filling is death. e.g. steak-and-kidney, mincemeat. How can you trust a pie? Answer: you can't unless, you make it yourself. I...
 The crust was perfect, and the filling was perfect, and the local grocery store even sells HP sauce (in its “ethnic foods” section, no less). So perfect. I had one cold for breakfast, which...
The Clean Plate Mandate
Kin and I have very different tactics for filling our dinner plates. He will take enough food so that, when he’s finished he’s done. He’s full. Me, I don’t take a lot – enough so that I can finish. The point, for me, isn’t to be full. The point is...
Birthday Dinners
If I have one big culinary regret, it’s that I never asked my grandma to teach me her recipes. She made two of my favorites growing up: fried chicken and chicken and noodles. As a kid, I’d insist that she cook my birthday dinner, which in hindsight was awfully selfish...
Recreations
I made sloppy joes for dinner the other night. The checker at the grocery store – the one who always tries to guess what I’m cooking based on the ingredients in my cart – asked what I had in mind. “Ooo. What’s your recipe?” she asked, as she scanned my...
Sunday Roast
“Got any special plans for Father’s Day?” the cashier asked us, as she rang up our groceries. “Just cooking that corned beef,” I replied, pointing to the brisket in her hand. To be honest, I’d planned on cooking it long before I realized today was Father’s Day. It’s a Sunday,...
Shepherd's Pie
I made shepherd’s pie for dinner last night. This isn’t a cooking blog. I’m not going to share the recipe here. I didn’t take any photos as I sautéed the minced lamb with carrots and onion or sealed casserole dish with mashed potatoes. Shepherd’s pie has been one my favorite...


| DOSE: |
|
oral |
Mushrooms |
(ground / crushed) |
| |
500 mg |
oral |
Vitamin C |
(pill / tablet) |
Let me start off by explaining that I am one of those very rare people that reacts very badly to THC, there is no such thing as a good weed high for me, paranoia doesn't describe what weed does to me, I think paranoia is when I become convinced someone in the room is a narc and cops are coming to bust me any second(typical weed paranoid story from friends).
What happens to me on weed is on a whole other level, more like delusional psychosis. I become convinced that every word from any person/tv show has some kind of horrific double meaning that I cannot figure out, that everything that has ever happened to me had some hidden agenda that I can only see while high on weed. Nothing can bring me back to reality accept facing the wall and sleeping it off. Someone talking in a voice too quiet for me to hear AUTOMATICALLY means they are ploting something against me, I have horrific 'realizations' about the nature of existance itself.
Its very very bad and I never ever smoke weed anymore because of it.
I always assumed this was because of the 'mild' disassociative effects of weed, I decided to test this theory by taking mushrooms the first day of my semester spring break. I got 60$ worth, I asked my roommate(who knows all about my weed reaction) that if I start to really freak out would he please turn everything off and go to sleep and I will take some sleeping pills and sleep it off. He agrees.
I divide the bag in half and grind the mushrooms up, I then wash it down with orange juice and take a chewable 500mg vitamin C tab. All on an empty stomach.
My source tells me that is enough to where I will be convinced the people in the posters on my wall are talking to me.
My friend downs the 2nd half of the shrooms, I play computer games and wait VERY nervous that any second now I am going to freak out and wake up the next day in a mental institution in a straight jacket.
After about 30 minutes I start to feel a little 'off' like I have had 2 or 3 beers, not quite messed up but not 100% normal. My heart is beating very fast, not due to the shrooms I think but just because I am so scared.
After an hour or so I am really feeling it, colors look much brighter and I feel euphoric, very nice, I start to calm down, I put on some dance music mp3s and use a 3d vis plugin for my mp3 player. The colors swirl together like on weed but much more strongly and I have no bad paranoia clouding the experience and brining me down. I go out to smoke with my roommate, the hallway looks really long and the floor is moving up in down like waves.
None of this wierds me out at all, it just makes me laugh. The cig smoke looks very trippy, we stare at trees for a while and they look very very cool, I am still not wierded out, and I fine if I really concentrate on something all the effects go away, I feel totally sober. Then I relax and watch more mp3 vis and I am having a blast.
At this point I am very euphoric, I become talkative and extremely energetic, I have tracers in my vision, no negative thoughts in my head, nothing can touch me.
I decide to put on a cheesy movie for a while, we put on Teenage Mutuant Ninja Turtles the live action movie.  I love this feeling.
I spend the rest of the night running around campus and being very open and friendly, and drinking orange juice like their is no tommorow, I spent 15$ on orange juice that night alone.
The sun finally comes up and I walk outside to have a last smoke, the hallway is bathed in yellow light and it looks so beautiful, I am at peice, I feel great, finally a drug I can do and not freak.
After my smoke I decide to see if I can force a bad trip somehow, I put on a really violent horror movie and listen to death metal mp3s, I still feel fine just slightly less euphoric due to the more serious subject matter.
All in all it was great, I had a lot of fun, and did mushrooms every night that week. I had no hangover the next days after that, just a slight euphoric feeling still.
I love shrooms and plan on doing them whenever possible.
Oh yeah BTW, the ONLY negative side effect is that I felt really dirty when the shrooms hit, I had taken a shower 6 hours before my trip but I could feel the oil on my hands and it grossed me out, I took a shower and changed into all clean clothes and felt way better.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


labeled
by None at 2022-04-26 11:41:19.closed
by None at 2022-04-26 13:27:21.review_requested
by None at 2022-04-26 10:57:10.ready_for_review
by None at 2022-04-26 10:57:14.referenced
by Jane Sandberg at 2022-04-26 13:34:47.merged
by Jane Sandberg at 2022-04-26 13:34:47.closed
by Jane Sandberg at 2022-04-26 13:34:48.head_ref_deleted
by Jane Sandberg at 2022-04-26 13:34:49.review_requested
by None at 2022-04-26 13:48:28.referenced
by Jane Sandberg at 2022-04-26 18:17:51.merged
by Jane Sandberg at 2022-04-26 18:17:51.closed
by Jane Sandberg at 2022-04-26 18:17:51.head_ref_deleted
by Jane Sandberg at 2022-04-26 18:17:52.this depends on #200
labeled
by None at 2022-04-26 18:43:32.labeled
by Kevin Reiss at 2022-04-25 22:06:36.labeled
by Eliot Jordan at 2022-04-26 16:34:10.assigned
by Eliot Jordan at 2022-04-26 16:34:10.labeled
by Eliot Jordan at 2022-04-26 19:20:24.Historically we've used a pull model for this - now all of our sources are us and under our control in some way. I'd like to use a push model so that remote services tell Figgy "hey this changed". That way if Figgy's down we can leave it to the other applications to retry.
Options I see:
/identifiers/:identifier/update
- Notify Figgy an identifier is updated.Something else...?
Whatever we do, we should probably allow the API to accept multiple identifiers being updated. Maybe even wildcards? So when a collection call number is updated it gets all of the components.
I vote for options 1 and 4. GraphQL doesn't seem appropriate for this use case. WebSub is interesting.
My colleague at the Princeton Development Office used WebSub in 2008 (then called "PubSubHubbub") to sync a number of our applications. I definitely think the Pub/Sub model is the way to go for this type of use case, so I'd say #4 seems most appropriate, and allows us to easily sync future systems with the same infrastructure.
Not sure what is involved in #1. Is the idea that it's just an API endpoint that waits for some system to send it an ID to then update?
I'm also a bit wary of GraphQL pubsub as I feel like we may have instances where we will want to sync systems in which GraphQL is not involved. It also seems a bit underdeveloped based on the docs.
I assume each of these solutions will also require some plugin/code to be written for ASpace that "publishes" data updates (or in the case of #1, makes an API request), correct?
I assume each of these solutions will also require some plugin/code to be written for ASpace that "publishes" data updates (or in the case of #1, makes an API request), correct?
We update from Pulfalight - my intention was to just have Pulfalight ping Figgy after an index job.
For 4 I'd have to look at the spec more than the cursory glance I gave it.
How would we handle Figgy having to be both the "Hub" and "Consumer" if we went that route?
Option 1 seems quickest to implement. Do the benefits of pubsub outweigh that consideration? Assuming pulfalight runs a background job, and the figgy endpoint also kicks off a job, I think we have a very low potential to lose these events.
Would we ever have other subscribers?
We grew consensus around #1.
Open questions:
I like the idea of a wildcard, also fine with a separate endpoint. this seems like a case where on the figgy side it might be worth looking into using async for the network IO, so I don't think we should send each as its own request.
labeled
by Trey Pendragon at 2022-04-25 23:56:33.labeled
by Trey Pendragon at 2022-04-26 23:57:17.labeled
by None at 2022-04-26 14:57:45.labeled
by Christina Chortaria at 2022-04-26 18:07:52.In order to see the page errors, in https://github.com/pulibrary/orangelight/blob/5f17327633c93ae6ac08664fad2bedb1e2fd5663/spec/support/capybara_selenium.rb#L66 I replaced Capybara.javascriptdriver = :seleniumheadless with Capybara.javascript_driver = :selenium. Then in the console and while the test was still running I could see: Access to fetch at 'https://figgy.princeton.edu/graphql' from origin 'http://<IP_ADDRESS>:50248' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I found a reference that with Rails 6 there is a change DNS Guard: hosts whitelist
see : https://getaround.tech/rails-6-unnoticed-features/.
Following this reference, in https://github.com/pulibrary/orangelight/blob/main/config/environments/test.rb, I set config.hosts << "https://figgy.princeton.edu/graphql"
, config.hosts.clear
, config.hosts << "http://<IP_ADDRESS>"
but it didn't seem to work.
unassigned
by Christina Chortaria at 2022-04-26 19:10:43.Coverage remained the same at 94.469% when pulling 2d22c86e9f4b31d60e4e25d8227012b464a7ce67 on jest-test-updates into 5f17327633c93ae6ac08664fad2bedb1e2fd5663 on main.
@sandbergja can you check again?
head_ref_force_pushed
by Christina Chortaria at 2022-04-26 19:14:22.head_ref_force_pushed
by Christina Chortaria at 2022-04-26 20:06:44.mentioned
by Jane Sandberg at 2022-04-26 20:08:04.subscribed
by Jane Sandberg at 2022-04-26 20:08:04.review_requested
by Christina Chortaria at 2022-04-26 20:10:38.referenced
by Jane Sandberg at 2022-04-26 20:18:53.merged
by Jane Sandberg at 2022-04-26 20:18:53.closed
by Jane Sandberg at 2022-04-26 20:18:53.head_ref_deleted
by Jane Sandberg at 2022-04-26 20:18:54.closed
by Christina Chortaria at 2022-04-26 20:47:54.Coverage increased (+0.06%) to 94.533% when pulling 1de352a1b1a838184f3f404616d7468e317f1288 on update-temp-loc-item into d458eac0e62b7dcca9369d795de0d09fb2cd8729 on main.
head_ref_force_pushed
by Christina Chortaria at 2022-04-26 20:28:44.referenced
by Christina Chortaria at 2022-04-26 20:47:53.merged
by Christina Chortaria at 2022-04-26 20:47:53.closed
by Christina Chortaria at 2022-04-26 20:47:54.head_ref_deleted
by Christina Chortaria at 2022-04-26 20:47:55.assigned
by Christina Chortaria at 2022-04-26 20:57:44.closing in favor of https://github.com/pulibrary/orangelight/tree/jest-test-updates
head_ref_force_pushed
by Christina Chortaria at 2022-04-26 16:15:00.head_ref_force_pushed
by Christina Chortaria at 2022-04-26 16:50:17.head_ref_force_pushed
by Christina Chortaria at 2022-04-26 17:08:32.closed
by Christina Chortaria at 2022-04-26 18:24:09.head_ref_deleted
by Christina Chortaria at 2022-04-26 22:27:33.assigned
by James R. Griffin III at 2022-04-26 14:11:43.assigned
by James R. Griffin III at 2022-04-26 14:12:17.assigned
by James R. Griffin III at 2022-04-26 14:12:36.assigned
by James R. Griffin III at 2022-04-26 14:12:48.referenced
by Hector Correa at 2022-04-26 17:45:41.merged
by Hector Correa at 2022-04-26 17:45:41.closed
by Hector Correa at 2022-04-26 17:45:42.head_ref_deleted
by Hector Correa at 2022-04-26 17:45:42.closed
by Hector Correa at 2022-04-26 17:45:41.As this seems to have been lowered below 100%, this should be reopened:
reopened
by James R. Griffin III at 2022-04-26 17:46:14.renamed
by James R. Griffin III at 2022-04-26 17:47:12.head_ref_force_pushed
by James R. Griffin III at 2022-04-26 14:03:30.head_ref_force_pushed
by James R. Griffin III at 2022-04-26 14:19:55.ready_for_review
by James R. Griffin III at 2022-04-26 14:20:36.head_ref_force_pushed
by James R. Griffin III at 2022-04-26 14:21:54.review_requested
by James R. Griffin III at 2022-04-26 17:46:44.closed
by Hector Correa at 2022-04-26 14:08:58.referenced
by Hector Correa at 2022-04-26 14:08:58.merged
by Hector Correa at 2022-04-26 14:08:58.closed
by Hector Correa at 2022-04-26 14:08:58.head_ref_deleted
by Hector Correa at 2022-04-26 14:09:00.labeled
by Kevin Reiss at 2022-04-26 22:56:16.assigned
by Trey Pendragon at 2022-04-26 00:07:50.referenced
by Trey Pendragon at 2022-04-26 01:22:43.renamed
by Shaun Ellis at 2022-04-26 17:03:51.I just want to check my assumptions about the Ask Us button:
It should look identical to the Ask Us button on the Library Website, but the behavior should be different. In other words, we are NOT implementing Live Chat, but rather the click should display the modal pop-up we currently use for Ask A Question on collection pages (see screenshot).
Is this correct, @faithc ?
There are two potential UX issues I see with this, although fairly minor. First, clicking on Ask Us should result in a title that is identical, whereas this one would be mismatched with the title being "Ask A Question". Second, people who are used to clicking on "Ask Us" for Live Chat in the Library site may be surprised that this feature is not consistent across our sites.
This is more a question for @ccleeton.
Could it say Ask Us A Question? and I see the issue with the consistency however I do think most of our users use the FA and not the main library page as much so I think it will be ok.
@ccleeton I was asking about consistency because I remember a majority of the participants in our most recent study got to the Finding Aids site via the Main Library site.
I can change it to "Ask Us A Question", I will just need to make the font smaller or the button bigger. I also wonder if we should reconsider the chat bubble icon if we are not doing Live Chat?
We can't handle live chat. We really just want a way from the main landing page that people can contact us. There isn't something right now. However that needs to look.
mentioned
by faith at 2022-04-26 16:59:08.subscribed
by faith at 2022-04-26 16:59:08.mentioned
by None at 2022-04-26 16:59:35.subscribed
by None at 2022-04-26 16:59:35.mentioned
by Christa Cleeton at 2022-04-26 17:15:44.subscribed
by Christa Cleeton at 2022-04-26 17:15:44.mentioned
by Christa Cleeton at 2022-04-26 17:47:06.subscribed
by Christa Cleeton at 2022-04-26 17:47:06.@eliotjordan I updated the refs to be full links - take another look?
head_ref_force_pushed
by None at 2022-04-26 18:25:17.mentioned
by Eliot Jordan at 2022-04-26 18:26:06.subscribed
by Eliot Jordan at 2022-04-26 18:26:06.Drafting this until there's an auth token required to view unpublished materials.
This should be ready for review again, working on the accompanying ansible PR
convert_to_draft
by Trey Pendragon at 2022-04-26 21:07:13.ready_for_review
by Trey Pendragon at 2022-04-26 23:06:47.referenced
by Trey Pendragon at 2022-04-26 23:57:01.


--- layout: default --- {% include banner.html %} {% include about.html %} {% include screencasts.html %} {% include news.html %} {% include publications.html %} {% include consortium.html %} {% include tools.html %}


--- title: SAP Concur App Center - Go To Market layout: default ---
Don't have access yet? Contact us at<EMAIL_ADDRESS>to get added to Partner Place.


Introduction
Smart reply is an end to end method for automatically generating short yet semantically diverse email repsonses. The feature also depends on some novel methods for semantic clustering of user-generated content that requires minimal amount of explicitly labeled data.
Google reveals that around 25% of the email responses are 20 tokens or less in length. The high frequency of short replies was the major motivation behind developing an automated reply assist feature. The system exploits concepts of machine learning such as fully-connected neural networks, LSTMs etch.
Major challenges that have been addressed in building this features includes the following:
- High repsonse quality in terms of language and content.
- Utility maintained by presenting a variety of responses.
- Scalable architecture to serve millions of emails google handles without significant latencies.
- Maintaining privacy by ensuring that no personal data is leaked while generating training data. Only aggregate statistics are inspected.
Smart Reply
Smart reply consists of the following components:
- Response Selection: An LSTM network processes the incoming messages and produces the most likely responses. To improve scalability and increase speed of processing, only approximate best responses are found.
- Response Set Generation: In order to maintain high quality, the responses are selected from a response state generated offline using semi-supervised graph learning approach.
- Diversity: After generating the most likely responses, a smaller set of responses are chosen among them to maximize the utility which requires enforcing diverse semantic intents among the presented options.
- Triggering Model: A feedforward neural network decides whether or not to suggest responses, which further improves the utility by not showing suggestions when they are unlikely to be used.
Background
The entire application of smart reply can be basically broken down into two core tasks:
- predicting responses
- identifying a target response space
While the task of finding the apt response has be attempted before, it has never been applied to a production environment at such a scale. It is this widespread use of the application that requires it to deliver high quality responses at all the instances. This is achieved by choosing the responses from a set of pre-identified response space.
Which leads to the second core task of identifying the target response space. This is achieved by using an algorithm called Expander Graph Learning Approach. It is used because it scales well to really large datasets and large output sizes. Generally used for knowledge expansion and classification tasks, smart reply is the first attempt to use it for semantic intent clustering.
Selecting Responses
The fundamental aim of smart reply is to find the most likely response given an original message text. i.e. given an original message \(o\) and the set of all possible responses \(R\), find,
In order to acheive this a model is built to score the responses and then response with the highest score is picked.
LSTM Model
- Since a sequence of tokens \(r\) is being scored conditional on another sequence of characters \(o\), the task is a natural fit for sequence to sequence learning.
- Input to the model is the original message \(\{o_1, o_2, \cdots o_n\}\)
- The output is the conditional probability distribution of sequence of response tokens given the input:
The distribution in \eqref{2} can be further factorized as,
In practice, the sequence of original message is fed to the LSTM, which then encodes the entire message in a vector representation. Then given this state, a softmax output is computed, which is interpretted as \(P(r_1|o_1, \cdots, o_n)\)(probability distribution of the first response token).
Similarly, as the response tokens are fed in, softmax at each timestep \(t\) is interpretted as \(P(r_t|o_1, \cdots, o_n, r_1, \cdots, r_{t-1})\)
Using the factorization in \eqref{3}, these softmax scores can be used to compute \(P(r_1, r_2, \cdots, r_m | o_1, o_2, \cdots, o_n)\).
Training involves the following points:
- maximize the log probability of observed responses, given their respective original messages, i.e.
- train using stochastic gradient descent using AdaGrad.
- training is done on a distributed system because of the size of the dataset.
- recurrenct projection layer helped improve quality and time of convergence.
- gradient clipping helps stabalize training.
Inference: At the time of inference one can feed in the original message and then use the output of the softmaxes to get a probability distribution over the vocabulary at each timestep. These can be used in a variety of ways:
- to draw a random sample from the response distribution. This is done by sampling one token at each timestep to feed it back into the model.
- to approximate the most likely response given the original message. This can be done greedily by taking most likely token at each timestep and feeding it back in. A less greedy strategy is to use beam search, i.e. take the top \(b\) tokens and feed them in, then retain the best \(b\) response prefixes and repeat.
- to determine the likelyhood of a specific response candidate. Done by feeding each token of the candidate and using softmax output to get the likelyhood of next candidate token.
Challenges
Response Quality
- In order to surface responses to the users, responses must be always high quality in terms of style, tone, diction, and content. Since the models are trained on real-world data, one has to account for the possibility where the most response is not necessarily a high quality response. Even the most frequent responses might not be appropriate to suggest to users because it could contain poor grammar, spelling or machanics (like you’re the best!) or it could also convey a sense of familiarity that is likely to be offensive (like thanks hon!) etc.
- While restricting the vocabulary can take care of issues such as profanity or spell errors, it would not be sufficient in averting a politically incorrect statement that can be formed in a wide variety of ways.
- Hence, smart reply uses a semi-supervised learning to build the target repsonse space \(R\) comprising of only high quality responses.
- Hence the model described is used to choose the best response among \(R\), instead of best response from any sequence of words in the vocabulary.
Utility
- Suggestions are most useful when they are highly specific to the original message and express a diverse intent.
- Generally the outputs from LSTM observed tend to (1) favor common but unspecific responses and (2) have little diversity.
- Specificity of the responses is increased by penalizing the responses that are applicable to a broad range of incoming messages.
- In order to increase the breadth of options presented to users, diversity is enforced by exploiting the semantic structure of \(R\).
- Utility of responses is also boosted by passing the incoming message first through a triggering model which decides whether or not it is appropriate for suggestions to pop up.
Scalability
- Scoring every candidate \(r \in R\) would require \(O(|R | l)\) LSTM steps where \(l\) is the length of the longest response.
- This would mean a growing response time as the number of responses in \(R\) increases over time.
- In general, an efficient algorithm for this purpose should not be a function of \(|R|\)
- In order to achieve this, the responses among \(R\) are organized as a trie, followed by a left-to-right beam-search but retain only the hypotheses that appear in the trie.
- This search process has a complexity of \(O(bl)\) where both \(b\) and \(l\) are in a range of 10-30, which greatly reduces the time it would take to generate the responses.
- Although the search only approximates the best responses in \(R\), its results are very similar to what one would get by scoring and ranking all \(r \in R\), even for a small \(b\).
- Also first pass through the triggering model, reduces the average time a message has to spend in LSTM computations.
Response Set Generation
- The goal of this step is to generate a structured response set that effectively captures various intents conveyed by people in natural language conversations.
- The target response space is required to capture both variablity in language and intents.
- The results are used in two ways - (1) define a response space and (2) promote diversity among chosen suggestions.
- Response set is constructed by aggregating the most frequently used sentences among the preprocessed data.
Canonicalizing Email Responses
- Involves generating a set of canonicalized responses that capture the variability in language.
- This is done by performing a dependency parse on all the sentences and then using the syntactic structure to generate a canonicalized representation.
- Words, phrases that are modifiers or not attached to the head words are ignored.
Semantic Intent Clustering
- partition the responses into semantic clusters where each cluster represents a meaningful response intent.
- all the messages within a cluster share the same semantic meaning but may appear different in structure.
- this helps digest the entire information present in frequent responses into a coherent set of semantic cluster
- because of the lack of data available to train a classifier, a supervised model cannot be trained to predict the semantic cluster of a candidate response.
- another hindrance in performing supervised learning is that the semantic space classes cannot be all defined a priori.
- hence the semi-supervised technique is used for achieving this.
Graph Construction
- Start by manually defining the clusters sampled from top frequent responses.
- A small number of responses are added as seed for the clustering.
- This leads to a base graph, where frequent responses are represented by nodes, \(V_R\). Lexical features (n-grams and skip grams upto a length of 3) are extracted for the responses and populated in graph as the feature nodes, \(V_F\). Edges are created between the pair of nodes, \((u,v)\) where \(u \in V_R\) and \(v \in V_F\). Similarly, nodes are created for manually labelled examples, \(V_L\).
Unsupervised Learning
- The constructed graph captures the relationship between the canonicalized responses via feature nodes.
- Semantic intent for each repsonse node is learnt by propagating intent information from manually labelled examples through the graph.
The algorithm works to minimize the following objective function for the response nodes:
where
- \(s_i\) is an indicator function equal to 1 if node \(i\) is a seed else 0.
- \(\hat{C_i}\) is the learnt semantic cluster distribution for response node \(i\).
- \(C_i\) is the true label distribution (i.e. for the manually provided examples)
- \(\mathcal{N}_{\mathcal{F}} (i)\) and \(\mathcal{N}_{\mathcal{R}} (i)\) represent the feature and response neighbourhood of node \(i\).
- \(\mu_{np}\) is the predefined penalty for neighbouring nodes with divergent label distributions.
- \(\hat{C_j}\) is the learnt label distribution for feature neighbour \(j\).
- \(w_{ij}\) is the weight of feature \(j\) in response \(i\).
- \(\mu_{pp}\) is the penalty for label distribution deviating from prior, Uniform Distribution \(U\).
Similarly, the objective is to reduce the following objective function for the feature nodes:
\eqref{5} and \eqref{6} are alike except that \eqref{6} does not have the first term as there are no seed labels for the feature nodes.
The objective functions \eqref{5} and \eqref{6} are jointly optimized for all the nodes. In order to discover the new clusters the algorithm is run in phases, in which randomly 100 new responses are sampled among the unlabeled nodes. These are treated as the potential new clusters and labeled with there canonicalized representations after which the algorithm is rerun and the process is repeated for the unlabeled nodes.
Cluster Validation
- Finally, the top \(k\) members from each semantic cluster are extracted and sorted by their label scores.
- The set of (response, cluster label) pairs are then validated by human raters.
Suggestion Diversity
- The LSTM model is trained to returned the approximate best response among the target response set.
- The responses are penalized if they are too general to be valuable to any user.
- The next challenge lies in choosing a small number of responses to display to the user which maximizes the utility.
- A straight-forward way of doing this can be to choose the top \(N\) responses and present them to the user. But in practice it is observed that such responses tend to be very similar. It is obvious to anyone that the likelihood of one of the repsonses being useful is greatest when none of the responses presented to the users are redundant, i.e. it would be wasteful to present a user with three responses that are a variation of same sentence.
- The second and more optimal approach to suggest responses to users would include enforcing diversity. This is achieved by:
- omitting redundant responses.
- enforcing negative or positive responses.
Omitting Redundant Responses
- The strategy states that a user should never see two responses with the same intent.
Intent can be thought of as a cluster of responses that have a common communication purpose.
- In smart reply, every suggested responses is associated with a exactly one intent. These intents are learnt using the semi-supervised learning algorithm explained above.
- The actual diversity strategy simple: the top responses are iterated over in order of decreasing score. Each response is added to suggestion list unless its intent is already covered by a response in the suggestion list.
Enforcing Negatives and Positives
- It is observed that the LSTM trained has a strong tendency towards positive responses, whereas negative responses generally get a low score.
- It might be reflective of the style of email conversations: positive replies are more common and when the replies are negative people prefer more indirect wording.
- Since, it is important to give out and option of repsonding negatively, the following strategy is followed:
If the top two responses (chosen from different intents) contain atleast one positive and none of the three responses are negative, the third response is replaced with a negative one.
-
A positive response is the one that is clearly affirmative. In order to find the negative response to be included as the third option, a second LSTM pass is performed, in which the search is restricted to only to the negative responses in the target set.
-
It might also be the case that an incoming message triggers exclusively negative responses. In which case, an analogous strategy for enforcing positives is employed.
Triggering
- This is a second model (in this case a fully-connected feed-forward neural network which produced probability score) that is responsible for filtering messages that are bad candidates for suggesting responses. These might include emails that require longer responses, or emails that do not require a response at all.
- On an average this system only decides that 11% of the incoming messages should get processed for smart reply. This selectivity further helps to speed up the process of analyzing the incoming emails, and decrease the time spent on LSTM and hence inturn reduce the infrastructure costs.
- The two main objectives that this system should fulful are:
- it should be accurate enough to decide when a smart reply should not be generated
- it should be fast.
- The choice of model is because it has been repeatedly observed that these ANN outperform linear models such as SVMs or linear regression on NLP tasks.
Data and Features
- Data includes the set of emails in the pair \((o, y)\), where \(o\) is an incoming message and \(y\) is a boolean true or false based on whether or not a email was replied to. For the positive class, only the messages that were replied to from a mobile device are considered.
- Since the number of emails that are not replied to are found to be higher, the negative class examples are downsampled to match the number of positive class examples.
- Features (unigrams and bigrams) are extracted from message body, subject and headers. Other social signals such as whether or not the sender is in receipent’s address book etc is also used.
Network Architecture and Training
- Feed forward neural network with embedding layer and three fully connected hidden layers
- Feature hashing is used to bucket rare words that are not present in the vocabulary.
- Embeddings are aggregated by summation within a features (like bigram etc.)
- Activation function: ReLu and Dropout layers are used.
- Trained using AdaGrad optimization technique.
Evaluation and Results
Data
- For the LSTM model data consists of incoming messages and its responses by a user.
-
For the triggering model, messages are used with the label describing whether or not they were replied to from a mobile device.
- The following preprocessing techniques are used:
- Language detection: non-english messages are discarded.
- Tokenization: messages and subjects are broken down into words and punctuations
- Sentence segmentation: sentence boundaries are detected in the message body
- Normalization: infrequent words and entities like personal informations are replaced by special tokens.
- Quotation removal: Quoted original messages and forwarded messages are removed.
- Salutation/close removal: salutations and closing notes are removed.
- After preprocessing the size of the training data is 238 million messages, which includes 153 million messages that have no response.
Conclusions
- Standard binary performance metrics are observed for triggering model: Precision, recall and area under the ROC curve.
- AUC of triggering model is 0.854
- For the LSTM model Precision, Mean Reciprocal Rank and Precision@K is observed.
- A model with lower perplexity assigns a higher likelyhood to the test responses, and hence should be better at predicting responses. Perplexity of smart reply is 17.0 (by comparison, and n-gram model with katz backoff and maximum order of 5 has a perplexity of 31.4)
A perplexity equal to \(k\) means that when the model predicts the next word, there are on average \(k\) likely candidates.
- In an ideal scenario the perplexity of the system would be 1, i.e. one knows exactly what should be the next word. The perplexity on a set of \(N\) test samples is computed using the following formula:
where
- \(W\) is the total number of words in the \(N\) samples.
- \(\hat{P}\) is the learnt distribution
-
\(r^i\) and \(o^i\) are the \(i-th\) repsonse and original message.
- The model is also evaluated on the response ranking. Simply put, the rank of the actual response with respect to other responses in R is evaluated. Using this, the mean reciprocal rank (MRR) is calculated using:
-
Additionally, Precision@K (for a given value of K, the number of cases for which target response \(r\) is within the topK responses that were ranked by the model) is also computed.
-
On a daily basis, the smart reply system generates 12.9k unique suggestions that belong to 376 unique semantic clusters, out of which the users utilized, 31.9% of the suggestions and 83.2% of the unique clusters.
- Among the selected responses, 45% are the 1st responses, 35% 2nd responses, and 20% 3rd responses.
- If using only the straight-forward approach instead of enforcing diversity, the click through rates drop by roughly 7.5%.
REFERENCES:
Smart Reply: Automated Response Suggestion for Email
Save time with Smart Reply in Gmail


Id: 298
Name: Robot Morty
Status: unknown
Species: Robot
Type:
Gender: Male
OriginName: unknown
OriginUrl:
LocationName: Citadel of Ricks
LocationUrl: https://rickandmortyapi.com/api/location/3
Image: https://rickandmortyapi.com/api/character/avatar/298.jpeg
Episode: ['https://rickandmortyapi.com/api/episode/10']
Url: https://rickandmortyapi.com/api/character/298
Created: 2017-12-31T20:37:30.747Z


PKCE Flow step 2
Retrieve Token using the PKCE Flow
← Back to main page
View on GitHub
PKCE Flow Sample - step 2
This is the redirect page, where the user lands after authentication.
Code verifier (see previous page):
Response:
Click button to launch function.
JS code:
Click button to show code.


{% extends "index.html" %} {% block contents %}
Conceived, designed and managed by David Faraci.
Developed by David Faraci and Graham Leach-Krouse.
Site powered by Flask © 2015 Armin Ronacher and contributors.
Automated email server adapted from @jpsarda.
Mobile “hamburger” menu adapted from CodePen.
Lots of code snippets due to the community at Stack Overflow.
FONT © 2004 Typadelic Fonts.
MARGY is copyrighted under the MIT License.
Bug reports and feature requests to GitHub.
Questions and comments to<EMAIL_ADDRESS>Did MARGY save you money? Please consider donating.