--- date: 2023-04-26 lastmod: 2023-08-02 title: "Building awesome internal tools" description: "Sharing 13 guidelines and ideas that worked for me, creating the best internal tools with love and care for the user." image: "/assets/blog/awesome-internal-tools/title-card.png" imageAlt: "A screenshot of one of my internal tools to manage content on my websites. The design is my own retro-pixel UI I love looking at; a dark base with bright blue, red, and green accents." linkTitle: "Good enough is just not good. Building better internal tools for everyone." banner: "/assets/blog/awesome-internal-tools/banner" bannerAlt: "A screenshot of the start screen one of my internal tools to manage content on my websites. The design is my own retro-pixel UI I love looking at; a dark base with bright blue, red, and green accents." summary: "
Internal tools often don't get the love and care they deserve. Here I'll share 13 general guidelines to build better internal tools that have helped me in the past.
" tags: ["post", "general"] ---As this is my personal blog, I sure hope every reader knows that my opinions will be part of it. Nevertheless, I want to emphasize this, especially for this article, that I put together based on my time in software development and what I experienced and what worked well.
Still, it always depends on different factors and the given context — am I my own user, work for a small team, a large company, hobby, professional, budget, and many more. With this out of the way, let's go.
Internal-facing tools can be a lot of things; large and small GUI applications, code libraries, script tools, APIs, or even workflows for teams. Quite often, in my past, those tools were rather technical.
Configuration through JSON, YAML, or XML; run through Jenkins, GitHub Actions, or a command-line script. A search that is based on regular expressions, a Domain Specific Language (DSL), a release job used by non-technical people triggered through a cURL call, or a REST API so good that it "documents itself".
I wrote this just for myself or my colleagues — I know, and they can ask me. Those designers just need to learn Git, my manager how to use cURL, they will manage. I will remember. In the end, I wrote the tool; what more?
This cannot be it. I am a user; my future self will not remember, and no, those designers should absolutely not be forced to learn Git*.
Internal tools often get kind of a different status assigned, may it be from ourselves to ourselves or in the larger context of a company. Bugs get accepted, complexities are sold as necessities, and documentation points to a chat thread, calling it a day.
I say no! Good enough is just not good. I should treat myself, my future self, my colleagues, and those that come after me better. Caring about internal tools and those users should be as natural as, hopefully, the care given to external users or anyone else.
Better internal tools will result in fewer errors, save time, and reduce costs. Removing friction is another reason to even create internal tools in the first place, so why only go half-way?
Good and comprehensive documentation reduces time spend searching for answers and help. Fewer bugs lead to less frustration and less time spent working around those issues. Happy users are more productive users; whether that is me or hundreds of others, it makes no difference.
All this increases confidence in a tool and, therefore, confidence in my own abilities or the ones of my team — reducing maintenance costs, increasing reusability, and getting easier buy-ins later from users, management, or the infamous future self.
I'll try to be constructive, not only talking about high-level concepts but, where possible, providing specific examples on how to create and improve internal tools. All of it should work, from a single person creating something amazing to a team working in a company, and I'll try to explain how this applies in those cases.
But be aware that this is neither an exhaustive list nor a set of rules. More like guiding on what worked for me in the past, from private projects to the years of development in companies, small and large. I did not eat wisdom with a spoon, though I'm passionate about tool development and want us all to build great software and workflows. On top of that, many of the points I'll bring up work for general software development as well.
With that being said, let's build awesome internal tools.
Developing internal tools means, generally speaking, developing for colleagues, yourself, or both. Users should not be treated differently because of that, though this is often the case. Talking about those tools, starting sentences with "This is just for …". Just for whom? The fundamental key to this endeavor is the person or group that will work with the tool.
The mindset is important. How we speak is important. This is not just; this is for my amazing users, for my capable colleagues; this is for the magnificent me, now and in the future. Always remember.
Too often, I see tools developed purely based on assumptions. Assuming how something should work, how people work together, and what the current process looks like. Sometimes, going ahead with a great idea and releasing it without having the actual user take a look at it before. Assumptions Driven Development.
This is a problem that can easily be resolved. Even with the greatest of ideas, ask and listen first. What is really wanted? Where is the current problem or friction? What needs to be automated? Planning goes a long way, and planning also means getting all the requirements right first by talking to the target audience.
What if this is just me? There it is again, just. Even for myself, I try to nail down what I really want. Do I need to automate those two clicks here? Do I always want to write regular expressions for my most powerful search yet? When I want to extend this software later, is this exhaustive plugin system really the right solution? I'm a technical person, but is a technical solution what I want?
It may seem obvious reading this, but reality shows it is not. Never assume, get all requirements, and involve users early. Just one benefit of internal tool development and reachable users.
Besides, involving users means letting them collaborate early, shaping the future of what they will use (probably) daily, increasing the emotional value attached to it, and therefore often being more forgiving on bugs or small issues.
Asking and listening is nice, but like a picture saying more than 1000 words, watching someone work with a tool, workflow, or library can give more insight than any question could. Quite often, what others see as "not worth mentioning" when talking about a workflow can offer great potential for optimization. Important here is to capture this session in any capacity, e.g., written down, pictures taken, or a video captured.
Too often I had a colleague skip over the fact they use two different tools for almost the same task, which for some reason resulted in saying "This is how we always did this". There is no blame for the user in this, as long-time usage often leads to blind spots.
Now, how do I watch myself work, creating tools for my own needs? Observe via screen recording! Starting a recording and letting it run for a duration of time, doing the usual tasks, testing a new tool, and working on integrating it into an existing workflow. And then review the recording. This will help identify barriers and reveal blind spots, giving a different perspective.
From my experience, automation and optimization of existing workflows and tools are not always what bring the biggest benefits. Looking at a day of work, where is all the time spent? Is it actually inside a tool, worth the effort to reduce four clicks to one, or is it context switching between different tools?
Often it is the second, context switching, or glue-work*. If this is the case, this is where effort should be spent.
Removing time in between can mean changing the tool landscape or composition. Where an old process uses three different tools to solve a given task, it can become clear that two of those tools are always used together. This offers the potential for unification, changing the composition, and removing lost time in context switching.
If tools cannot be unified, it is worth looking into other ways to reduce time. There could be a specific feature needed in one tool that can be transferred to another. Even if this means duplication, it can be worth it.
What if, inside my tool landscape, one tool is owned by another team or person? Talk to them, listen, show them the problem, and, in the best case, give them ideas on how to solve it. Or try working with them on solving the issue. If this is for any reason not feasible, or they can or will not help, try a different way. Feature duplication, contributing to an external codebase — get creative.
And sometimes, accept what is given. Create documentation about the issue and what was tried and discussed, and move on, spending your valuable time elsewhere.
There once was a documentation tool from a well-known company. It offered all one can dream of: editing without technical knowledge, a visual editor, rich-media support, integrations into other tools, even sharing documents with external users, and many more features. Yet no one wanted to use it. People even reacted with disgust, calling it a graveyard and worse. "Why?", one might ask. It was not sexy.
Even if a bit exaggerated, more often than not, looks can be the reason a totally capable tool is not accepted by users. What counts as good-looking is, of course, very subjective. The peak of beauty for one can be jarring for others.
When working alone and creating tools for myself, it can be whatever I like most. Personally, I love a retro-futuristic style, cassette futurism, so I developed a theme and corresponding libraries I can use for all my tools. It is a retro pixel style, dark but with brightly colored accents, and otherwise kept very simple. The image in this article shows the exact theme in question. I love looking at it and using my tools.
In a company, for many different users, it can be best to get someone who has knowledge of forming the user experience with design background (UI/UX). Much can be learned and taught, but a professional is a professional — and best utilized from the beginning if available.
If that's not an option, there is no shame in copying the style of others. One of the powers of developing an internal tool is freedom, including the freedom to copy. There are many great examples out there that can be adapted to your use case. Alternatively, a theme library can be another option.
For the commonly used operating systems, Apple offers a list of great resources for human interface guidelines; Microsoft provides resources on how to design and code apps for Windows; and there is even a GTK+ list of human interface design guidelines. For Dear ImGUI, there is a great GitHub issue with lots of comments about designs and themes.
The W3C's community group Open UI offers some great resources for web-based design systems. The Design System Repo is another great choice with examples, articles, and tools.
Looks are not restricted to GUI applications. A terminal UI
is UI, too; a CLI can look nice; help text printed via
--help
formatted to be more readable. Even further, error
messages should "look good", aka. be very readable by a human.
Instead of directly printing an error, the thought should always be, "What error message actually helps?". Only showing what is directly helpful to resolve the problem. There can also be an error code or an additional tool to get further guidance on a problem. And if the user cannot do anything, how about not showing an error at all? Try to tell the user what will happen next, run a recovery, or, in the worst case, restart, but be transparent.
Test driven development is nice, but have you ever tried documentation-driven development? It is the simple concept of writing the documentation first, before anything else. Specifying how a library is used, a program should work, an API look, and a CLI behave — for the user.
This way of starting a project made the biggest change for my work, for the better. Usually I started with writing code; sometimes tests came first, sometimes not. Documentation always came later, always; sometimes never.
From the day I started working documentation-driven, my tools got better, APIs more usable, extendable, and readable. This may sound like an exaggeration, but it is not. This really changed how I approach any tool since then.
This works on any scale, too. When creating a new repository, a README should be the first file filled in and final. How to use the code, or library, in detail for all that is planned. It can also be applied to a single new feature for a bigger codebase or the next iteration of an application.
It makes me really think about how I want something to be used in the best possible way, on a detailed level. Being the best version of myself, I implement tests next, including all code examples from the documentation, if present. Not because someone said this is how I should do it, but because it solves my next set of problems, the technicalities.
At that point, I will hopefully have documentation, tests, and a big smile on my face. No matter how my implementation now looks, it is tested and can be used with an API I'm actually happy with.
Even on internal tooling, tackling a large new application or feature by starting off with a prototype is crucial to its successful adoption. A prototype in that context can be many things: a dummy created with a design tool; screens of what to expect; documentation explaining what will be available, going back to the documentation-driven approach.
It is not important what the prototype is, but that it exists and can be used to iterate with users. If future users are already happy at that stage, they will look forward to actually working with the new tool they get, knowing what to expect.
What if they're not happy? Iterate! Until they are happy. This can sometimes feel tedious, is often hard, and can take quite some time. But this initial time spent is well worth it, avoiding late conceptual changes and bigger refactors.
Some great tools to create visual prototypes are Penpot, free, open-source, and can even be self-hosted; Figma, which offers a free tier or a subscription-based price; and Sketch, paid with either a monthly subscription or a one-time payment, also offering free tiers for education.
At this point, looking at all the previous guidance, the problem space is fully understood, the documentation is already written, a prototype is approved by happy users who look forward to getting a new shiny toy, and tests may be implemented as well, giving the tool implementer the highest confidence to actually go into development.
This may sound like an unreachable scenario, and as context is everything, it sometimes is, but it is a scenario to strive for. In the end, as guidelines go, it is all about picking what works best for a given situation.
As a small mental exercise, look at an existing internal tool and think about what would need to be done to make it public. Is it a lot? Usual candidates are missing documentation, a user experience to be improved, or no way to monitor if everything actually works.
This is not about actually going public, as a lot of those tools cover internal company processes or are integrated into systems that can not be disclosed for any reason. This is purely about the what-if, from a user perspective, and the therefore emerging question of Why?
Can my colleagues not get the best experience? Can I? Why is that? Thinking about what is necessary to go public can be a valuable exercise to harden and improve a tool. One of those, often neglected, is monitoring.
Why should I monitor a tool used by a few? They will just write me when something does not work, won't they? Often not. For every user who wrote a bug ticket or a message in a chat, even more did not. Sometimes they find creative solutions, working around a problem or limitation of a tool, but in the end, they spend more time overall.
Monitoring will help catch this early. Having a central place for where your logs go, observing application performance, receiving alerts on errors, and recording user sessions when problems keep them stuck. There are many aspects to monitoring, and it all depends on the needs and goals set.
It is valuable to gather information to help the users, solve problems quicker, and catch errors early. The more robust and hardened the software, the smaller the maintenance cost, saving time for everyone.
In the past, I had some great experience with Datadog and Sentry, both great tools to support different monitoring needs. To be fair, always in the context of multiple users, not when I worked on my own.
This is the tricky one and, quite often, the hardest requirement. Creating a new tool to replace one or more already in existence. There can be many reasons why a full replacement is needed, and before even considering it, it should always be evaluated if one or more tools can be refactored or improved instead. But when the decision is made, a big task lies ahead.
An often very optimistic view is that a subset of features in a new tool will be enough to start replacing the existing one. This is not true; a new tool will need feature parity to get user acceptance. If this is not the case, users will, when given the option, continue using the old tool and workflow.
It is possible to bring users over to a not yet fully feature-complete replacement when providing a clear benefit that makes it worth it with a subset of the functionality. Nevertheless, all previous tasks need to be solvable in some capacity — with the old tool, a temporary alternative, or a new minimal version of what is already in place.
What does help while developing the replacement in parallel is a feature freeze on the old tool. It is also well worth it to reuse what is possible, enabling a faster go-to-user. Reusing does not only mean code or design; it can also be a data format. Being able to run new and old in parallel is a huge benefit in this transition period.
Regardless of approach, the main goal needs to be that the new tool does provide a clear benefit, not just recreating what already existed (see point 3), with a 100% adoption rate. Not planning to retire the old tool is a mistake that will increase maintenance costs.
Rolling out a new release should be done with confidence and transparency. Confidence in having a setup that allows easy rollouts of new features to all users and being transparent about what will be released by announcing the changes. A good changelog will make a difference.
Changelog generation is a very common practice that involves taking commit messages and packing them into a list of changes. Often done with tools like Commitizen, where commit message rules define change log categories and content — I would not use this for users.
This kind of generated changelog is very technical and may be useful for developers working on a tool, but not for the end user. A good user changelog is human-readable, with focus on explaining or even showing new features and what user-reported issues were fixed.
It doesn't even need to be complicated or have a lot of text — images or recordings go even further. Anything that helps your user understand what is new and how it works, maybe even making them excited to try out the new release.
Ever heard "When we finish this tool, we build the next"? You're never done. Every new tool comes with new responsibilities. Fixing bugs, supporting new operating systems, and adding features. Saying a tool is done equals abandonment.
This is not a problem but an opportunity — instead of creating a new tool, an existing one can be extended. Alternatively, maybe there is something "off the shelf". Before creating a new one, all options need to be considered.
Now, when creating a new tool and keeping future responsibility in mind, extensibility should be considered. Giving the user methods to extend the tool, write plugins, create visual extensions, and support admin roles that can configure aspects for others. Generally, making it possible for users to solve new problems with what is given.
Going the extra mile is worth it. As said in the beginning, "good enough is just not good". Of course, this is not always the case, but we should all challenge ourselves to really go above and beyond.
Thinking from the users' perspective: fixing bugs, for example with reoccurring bug squashing days; getting regular feedback, this could be done by sending out short user surveys*; removing friction by looking at the time spent between tools; collaborating with others, not stopping at team borders.
In the end, it shouldn't even be going the extra mile; it should never be good enough. It should be going all the way, treating the target audience with respect and care and creating amazing internal tools.
It turned out I had more to say about tool development than I initially expected. Even though I numbered every part, there is no associated order; I rather tried to tell a coherent story. Like I initially said, context will decide what is important; sometimes I do a few, sometimes everything.
As guidelines go, I pick, mix, and match as I please. Though if there is one thing to remember between tool creator and user, as the great Bill and Ted said, "Be excellent to each other".
Until then 👋🏻


Turkey starts repatriation of captured Islamic State militants
by ReutersTurkey has started the repatriation of captured Islamic State militants, state broadcaster TRT Haber said on Monday, after the Turkish interior minister warned last week that Ankara would do so even if the prisoners had their citizenships revoked.
It was not immediately clear how many jihadists would be repatriated. President Tayyip Erdogan was cited as saying on Friday that there are 1,201 Islamic State prisoners in Turkish prisons, while Turkey had captured 287 militants in Syria.


Tenders
Find tendering opportunities with the Government of Manitoba.
Aboriginal Procurement Initiative
The objective of the Aboriginal Procurement Initiative is to increase the participation of Aboriginal peoples and suppliers in providing goods and services to the Manitoba Government.


BEFORE THE MADURAI BENCH OF MADRAS HIGH COURT DATED: 28.04.2017 CORAM THE HONOURABLE Mr.JUSTICE T.S.SIVAGNANAM AND THE HONOURABLE Mr.JUSTICE N.SESHASAYEE W.P.(MD)No.3644 of 2017 and W.M.P.(MD) No.2933 & 2934 of 2017 Ganasekar ... Petitioner Vs. 1.The Chairman (FAC) Tamil Nadu Pollution Control Board, 76,Mount Salai, Guindy, Chennai ? 600 032. 2.The District Collector, Madurai District, Madurai. 3.The Commissioner, Madurai City Corporation, Madurai. 4.The District Environment Engineer, Tamil Nadu Pollution Control Board, Kappaloor, Madurai. 5.The Superintending Engineer, Madurai Electricity Distribution Circle ? Metro K.Pudur, Madurai. 6.The Assistant Commissioner, Zone ? 2, Race Course Road, Madurai Corporation, Madurai. 7.The Assistant Engineer (O&M) TANGEDCO / Sellur Kalpallam, Palam Station Road, Madurai ? 625 009 8.Nagarajan ... Respondents PRAYER: Writ Petition is filed under Article 226 of the Constitution of India praying for issuance of a Writ of Certiorari to call for the records pertaining to the impugned proceedings passed by the first respondent in Proc.No.T8/TNPCB/F.23855/MO263/EB/MDU/2017, dated 08.02.2017 and T8/TNPCB/F.23855/MO263/A/MDU/2017, dated 08.02.2017 and quash the same. !For Petitioner : Mr.M.Senthil Kumar ^For R1 & R4 : Mrs.Reeta Chandra Sekar For R2 : Mr.S.Chandra Sekar, Government Advocate For R3 : Mr.J.Gunaseelan Muthiah, Government Advocate For R5 & R7 : No appearance For R6 : No appearance For R8 : Mr.Veilkani Raju :ORDER
[Order of the Court was made by T.S.SIVAGNANAM, J.] Heard the learned counsel for the parties.
2. In this writ petition, the petitioner challenges the proceedings issued by the first respondent/the Chairman (FAC), Tamil Nadu Pollution Control Board, Chennai, dated 08.02.2017, in and by which direction has been issued to the Electricity Board as well as the District Collector to disconnect the electricity supply for the unit in exercise of the powers conferred under Section 31A of the Air (Prevention and Control of Pollution) Act, 1981 as amended in 1987. This has has a case chequered history and this is the third round of litigation before this Court.
3. Earlier, the 8th respondent had approached this Court and filed W.P.(MD).No.1956 of 2016 to forbear the Official respondents from permitting the petitioner herein to run the industry in the name and style of Gnanam Ever Silver Pattrai at the place in question and to immediately take action for violation of the Public Health Act and Madurai City Municipal Corporation Act. The said writ petition was disposed of by an order dated 06.01.2017, by the Division Bench.
4. At this juncture, it would be relevant to take note of the relevant portion of the order made in W.P.(MD). No. 1956 of 2016, Paragraph Nos.4, 5, 6, 7, 9, 10 and 13 are as follows:
?4. The main grievance of the petitioner is that in spite of his complaint about the usage of heavy power equipments and machineries, which resulted in heavy noise and pollution in that area, no action was taken by the respondents 1 to 3. It is to be noted that the fourth and fifth respondents, without having licence to carry on the business, are running the industry. Hence, he sought for a direction to consider his representation and pass orders.
5. The second respondent has filed a counter-affidavit stating that notice under Section 41(8), 42(b), 44 and 134(1) of the Tamil Nadu Public Health Act was issued to the fourth respondent on 29.01.2016, directing the fourth respondent not to use the machineries after 10.00 p.m., till 06.00 a.m., and also directed the fourth respondent to take steps to reduce the sound of machineries.
6. The third respondent has also filed a counter-affidavit stating that the petitioner has given a complaint against the operation of M/s.Gnanam Ever Silver Pattarai, which is located next to the petitioner's house and because of usage of heavy machineries, there were severe vibration, noise pollution and public nuisance. Further, according to the petitioner, the Unit is running without local body licence and building plan approval. The complaint of the petitioner was forwarded to the Commissioner of Madurai Corporation to take action under the Local Body Act and the Public Health Act, vide letter dated 05.11.2015.
7. It is further stated in the counter-affidavit that another petition was received from the petitioner on 08.02.2016 against the same Unit. Based on the said complaint, the Unit was investigated on 12.02.2016 by the Assistant Engineer, Tamil Nadu Pollution Control Board, Madurai and it was observed thus:
"The unit was under operation.
The unit is located in the residential area.
The unit has provided one lathe, one plate turning machine, 4 no's of spinning/shaping machine, 2 No's of polishing machine and a welding machine It is reported that the lathe is not under operation for more than 8 months.
It is also reported that 1 no.of spinning/ shaping has been relocated (i.e. away from Complainant house) based on the request from complainant 4 months before.
It was found that the unit has not provided any noise absorbing materials or any vibration controlling materials to the machinery and in the unit's premises.
It is further to submit that no action taken reports has been received from the Commissioner, Madurai Corporation with respect to the previous complaints forwarded from this office."
9. Pursuant to the same, a show cause notice was issued to the Unit under the Water Act and Air Act for running the industry without valid consent. The Unit, by reply letter dated 07.05.2016, has stated that it has removed all the machineries installed nearer to the complainant's house and requested to grant one month time for removal of few of machineries in other part of the Unit i.e., Shed No.2-II.
10. Based on the reply of the Unit, it was again inspected by the Assistant Engineer, Tamil Nadu Pollution Control Board, on 20.05.2016 and on inspection, it was found that the Unit was under operation, but all the machineries adjacent to the petitioner's house were removed, except 2 numbers of welding machines and the manual sheet turning machine.
13. However, a perusal of the counter-affidavits filed by the second and third respondents would go to show that on receipt of the complaint preferred by the petitioner, the officials concerned are taking steps immediately. In fact, the second respondent has directed the Unit not to use the machineries after 10.00 p.m., till 06.00 a.m., and the third respondent has also constantly monitored the position of the Unit. When the official respondents have taken action against the Unit, this Court need not give any further direction. Therefore, recording the statements made by the Tamil Nadu Pollution Control Board in the counter-affidavit, more particularly, their undertaking that as soon as they receive the report from the Joint Chief Environmental Engineer (Monitoring) Madurai, they would take further action on the complaint of the petitioner, the Writ Petition is closed. No costs. Consequently, the connected miscellaneous petition is also closed.?
5. Thus, the Writ Petition stood disposed of by recording the statement given by the Tamil Nadu Pollution Control Board in the counter affidavit and the undertaking given by the Joint Chief Environmental Engineer (Monitoring), Madurai, that they would take further action on the complaint of the petitioner.
6. The grievance of the petitioner is that the impugned proceedings have been issued without any reference to the earlier orders passed by this Court, wherein the Court has taken into consideration all the factors. It is seen from the records placed before this Court that the Joint Chief Environmental Engineer (Monitoring), Madurai has conducted a public hearing on 11.07.2016, in which the petitioner has also participated, wherein the petitioner has stated that he has applied for permission from the Madurai Corporation and also will obtain the appropriate clearance from the Tamil Nadu Clearance Board within 15.08.2016. Subsequently, the petitioner filed another Writ Petition in W.P.(MD).No.10721 of 2016 for a Writ of Mandamus to direct the respondents to permit him to run the said factory. The said writ petition was dismissed for non-prosecution by the Division Bench, by order dated 04.08.2016. Thus, it is evidently clear that the Writ Petitioner has failed to obtain requisite clearance which he had undertaken to obtain at the time of personal hearing, on 11.07.2016. Hence, there is no error in the impugned proceedings. Accordingly, the Writ Petition fails and the same is dismissed. However, the dismissal of the Writ Petition will not prevent the petitioner from approaching the Authorities for necessary approvals. No costs. Consequently, the connected Miscellaneous Petitions are closed.
7. After the above order was passed, the learned counsel for the petitioner submitted that domestic electricity connection alone may be restored. In this regard, the petitioner shall give a representation to the seventh respondent, who shall consider the same in accordance with law.
To
1.The Chairman (FAC) Tamil Nadu Pollution Control Board, 76,Mount Salai, Guindy, Chennai ? 600 032.
2.The District Collector, Madurai District, Madurai.
3.The Commissioner, Madurai City Corporation, Madurai.
4.The District Environment Engineer, Tamil Nadu Pollution Control Board, Kappaloor, Madurai.
5.The Superintending Engineer, Madurai Electricity Distribution Circle ? Metro K.Pudur, Madurai.
6.The Assistant Commissioner, Zone ? 2, Race Course Road, Madurai Corporation, Madurai.
7.The Assistant Engineer (O&M) TANGEDCO / Sellur Kalpallam, Palam Station Road, Madurai ? 625 009..


Option layout and styling can be customized with an option template.
To do this, add an <ng-template>
element with parameters #optionTemplate
and
let-option="option"
as child to the
<ng-select>
element. The option template can now be
defined in the <ng-template>
element, in which
option
can be used to access the
IOption
object.
In the example below, a template is defined to show a flag icon in front of the country name using the famfamfam flags icon library.


NIIT University,Neemrana Rajasthan
B.Tech in Computer Science Engineering (2018-2022)
CGPA : 9.16
Python Development | Web Development | Machine Learning | Data Science
Proactive problem solver with excellent communication abilities and strong collaborative skills. Looking for an entry level position as a Software Engineer. Coming with strong programming experience in web development and ML/DL.
B.Tech in Computer Science Engineering (2018-2022)
CGPA : 9.16
Python, MySQL, C++, Java, Web Scraping, Data Structures and Algorithms, Web Development – HTML CSS & JavaScript, Machine Learning, Natural Language Processing, Tableau.
Django, Flask, Scikit Learn, Keras.
Team Work, Team Motivation, Leadership , Problem Solving.
This is an ecommerce website for pharmacy products which basically uses the Django framework from Python and Postgresql as the database. Languages Javascript, HTML and CSS are used. This website has many functionalities like auto-complete,cart,orders,and payment.
This research is based on stock prediction using Deep Learning and Sentiment Analysis. Tensorflow, keras frameworks from python are used.The Dataset is made form scratch using web scraping.
This an on-going project which is built upon django,javascript,html and css. This application mainly focuses on how to make sharing easy. Application provides you the file sharing option by which you can share the files to the people who are connected through your network.
This is an end to end machine learning project used to predict if a person is suffering from diabetes or not.Algorithm used in this project is Random forest. All the machine learning pipeline steps are carried out and deployed in the online cloud platform Heroku,Flask is used as the framework.
This project mainly focus on predicting the toxicity level of the sentence.For example if we give a sentence it predict the toxicity level in these categories threats, obscenity, insults, and identity-based hate.This can be used to categorize comments in twitter or any official website. The data set for this project is taken from kaggle.Algorithm used in this project is LSTM . Framework used Tensorflow and keras also nltk library from python
In this project a person can feed all the details and number of units used then the website will create an electricity bill in PDF form. I have used Django as the framework and bootstrap for front-end design.
I would love to hear from you, connect with me!!


Our Pricing
Annually
Monthly
Basic
$19.99
$199.99
500 GB Storage
2 Users Allowed
Send up to 3 GB
Professional
$24.99
$249.99
1 TB Storage
5 Users Allowed
Send up to 10 GB
Master
$39.99
$399.99
2 TB Storage
10 Users Allowed
Send up to 20 GB


Questions, comments, ideas, or concerns? We want to hear from you.
If you need to contact the SNHC for clinic information or follow-up questions regarding your visit, please call or email our board. Contact information, and location on clinic days is found below:
Timothy Rooney
Grace Keane
Nisha Bhat
Jack LeClair
Priyanka Parameswaran
Kim Johansson
Sajal Tiwary
Nick Becker
Corey Vural
Alex Scott
Lade Sogade
Avira Som
Meg Landon
Nicolas Ledru
Arjav Shah
Adam Surti
Sophie Evans
Benji Katz
Andrew Qi
Artur Meller


Welcome to the photography section of my portfolio. This section looks through my work in the areas of studio photography and image manipulation.
My photography work in the studio environment consists of headshots and product shots. These shots implemented the use of key, fill and back lighting. Over the course of this module, I have taken part in four studio shoots, two of which were for purposes of examination.
My collection of photography work can be viewed below. A description of the photograph in question can be viewed by simply clicking on the thumbnail.


This section describes how messaging applications can use the Message Group feature provided by the Broker.
The following examples show how to create a message group queue that enforces ordered group consumption across multiple consumers.
Example 1.22. Message Group Queue Creation - Python
sender = connection.session().sender("msg-group-q;" +
" {create:always, delete:receiver," +
" node: {x-declare: {arguments:" +
" {'qpid.group_header_key':'THE-GROUP'," +
" 'qpid.shared_msg_group':1}}}}")
Example 1.23. Message Group Queue Creation - C++
std::string addr("msg-group-q; "
" {create:always, delete:receiver,"
" node: {x-declare: {arguments:"
" {qpid.group_header_key:'THE-GROUP',"
" qpid.shared_msg_group:1}}}}");
Sender sender = session.createSender(addr);
Example 1.24. Message Group Queue Creation - Java
Session s = c.createSession(false, Session.CLIENT_ACKNOWLEDGE);
String addr = "msg-group-q; {create:always, delete:receiver," +
" node: {x-declare: {arguments:" +
" {'qpid.group_header_key':'THE-GROUP'," +
" 'qpid.shared_msg_group':1}}}}";
Destination d = (Destination) new AMQAnyDestination(addr);
MessageProducer sender = s.createProducer(d);
The example code uses the x-declare map to specify the message group configuration that should be used for the queue. See the AMQP Messaging Broker user's guide for a detailed description of these arguments. Note that the qpid.group_header_key's value MUST be a string type if using the C++ broker.
When sending grouped messages, the client must add a message property containing the group identifier to the outgoing message. If using the C++ broker, the group identifier must be a string type. The key used for the property must exactly match the value passed in the 'qpid.group_header_key' configuration argument.
Example 1.25. Sending Grouped Messages - Python
group = "A"
m = Message(content="some data", properties={"THE-GROUP": group})
sender.send(m)
group = "B"
m = Message(content="some other group's data", properties={"THE-GROUP": group})
sender.send(m)
group = "A"
m = Message(content="more data for group 'A'", properties={"THE-GROUP": group})
sender.send(m)
Example 1.26. Sending Grouped Messages - C++
const std::string groupKey("THE-GROUP");
{
Message msg("some data");
msg.getProperties()[groupKey] = std::string("A");
sender.send(msg);
}
{
Message msg("some other group's data");
msg.getProperties()[groupKey] = std::string("B");
sender.send(msg);
}
{
Message msg("more data for group 'A'");
msg.getProperties()[groupKey] = std::string("A");
sender.send(msg);
}
Example 1.27. Sending Grouped Messages - Java
String groupKey = "THE-GROUP";
TextMessage tmsg1 = s.createTextMessage("some data");
tmsg1.setStringProperty(groupKey, "A");
sender.send(tmsg1);
TextMessage tmsg2 = s.createTextMessage("some other group's data");
tmsg2.setStringProperty(groupKey, "B");
sender.send(tmsg2);
TextMessage tmsg3 = s.createTextMessage("more data for group 'A'");
tmsg3.setStringProperty(groupKey, "A");
sender.send(tmsg3);
The examples above send two groups worth of messages to the queue created in the previous example. Two messages belong to group "A", and one belongs to group "B". Note that it is not necessary to complete sending one group's messages before starting another. Also note that there is no need to indicate to the broker when a new group is created or an existing group retired - the broker tracks group state automatically.
Since the broker enforces group policy when delivering messages, no special actions are necessary for receiving grouped messages from the broker. However, applications must adhere to the rules for message group consumption as described in the AMQP Messaging Broker user's guide.
Apache Qpid, Messaging built on AMQP; Copyright © 2015 The Apache Software Foundation; Licensed under the Apache License, Version 2.0; Apache Qpid, Qpid, Qpid Proton, Proton, Apache, the Apache feather logo, and the Apache Qpid project logo are trademarks of The Apache Software Foundation; All other marks mentioned may be trademarks or registered trademarks of their respective owners


REVIEW
By Joy Wyse, the SILVER Screen Critic
One Man's Hero, Starring Tom Berenger, Daniela Romo, Patrick Bergin, Joaquim de Almeida, Stephen Tobolowsky. Directed by Lance Hool.
Most historical films produced in the United States are presented with the Americans as the `good Guys'. One Man's Hero dares to do otherwise. It tells the true story of the San Patricios who fought against America in the Mexican-American War.
At the time of the potato famine in Ireland, numerous emigrants arrived at our ports seeking work and citizenship. They were greeted as they got off the boat by Army recruiters who promised American citizenship in return for a hitch as a soldier. It was an offer too good to refuse. These Irish could have a roof over their heads, three meals a day, and receive payment that they could use to bring their families to this land of opportunity. And, there was no war going on.
Those that arrived at Galveston and such were stationed in Texas, mostly in Southern Texas, near the Mexican border. Tom Berenger plays John Riley, an Irishman who has risen to the rank of Sergeant. The Commanding officer is a fair man and a good leader, but when he is away, his second-in-command, Captain Gaine, (Steve Tobolosky) takes a sadistic enjoyment in tormenting the Irish. When Sgt. Riley asks for a pass to go to Mass he is chastised by this tyrant for cavorting with the enemy, although he issues the pass. Once at church, Sgt. Riley finds several other Irish who are AWOL in order to attend Mass.
The underlying question that is asked is: What about a man's freedom of religion? By attending Mass, they were not pledging allegiance to Mexico. They were simply honoring their God. Of course, it was felt that they were placing allegiance to Rome above faithfulness to America.
Although Sgt. Riley could safely return to camp with no repercussions, he elects to stay with his men in an attempt to obtain justice for them.
It is a beautifully taught history lesson and I highly recommend it. You will find yourself questioning your awareness of the past as you have learned it. What else is there of which we are unaware? I give it B+ for this reason. I definitely want to see it again.
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Mino Nakura
Hi, I’m Mino. I like working on cool things with cool people. I’m currently working as a Software Engineer at Starfish Space.
I graduated from the University of Washington with a B.S./M.S degree in Computer Science. I have had the pleasure of working as a Research Assistant under Chris Xie and Michael Jae-Yoon Chung. In the past, I also interned at Google X (Everyday Robots), Carnegie Robotics, and Microsoft.
news
| May 1, 2023 | Started working at Starfish Space! |
|---|---|
| Jun 18, 2022 | Graduated from the University of Washington! |
| Jun 14, 2021 | Interned at Google X / Everyday Robots |


class ConnectivityHelper
Helper class to check connection status amd read out connection type. This code was taken from old sevenonemedia SDK.
<init> |
Helper class to check connection status amd read out connection type. This code was taken from old sevenonemedia SDK. ConnectivityHelper() |
CELLULAR_NETWORK_2G |
val CELLULAR_NETWORK_2G: String |
CELLULAR_NETWORK_3G |
val CELLULAR_NETWORK_3G: String |
CELLULAR_NETWORK_4G |
val CELLULAR_NETWORK_4G: String |
CELLULAR_NETWORK_UNKNOWN_GENERATION |
val CELLULAR_NETWORK_UNKNOWN_GENERATION: String |
ETHERNET |
val ETHERNET: String |
UNKNOWN |
Connection types defined in API spec. val UNKNOWN: String |
WIFI |
val WIFI: String |
getConnectionType |
Check type of connection. fun getConnectionType(context: Context): String |
isConnected |
Check is device is connected. fun isConnected(context: Context): Boolean |


Manage and analyze animal movement data. The functionality of 'amt' includes methods to calculate track statistics (e.g. step lengths, speed, or turning angles), prepare data for fitting habitat selection analyses (resource and step-selection functions), and simulation of space-use from fitted step-selection functions.
| Version: | <IP_ADDRESS> |
| Depends: | R (≥ 2.10) |
| Imports: | broom, circular, dplyr (≥ 0.7.0), fitdistrplus, FNN, geosphere, graphics, grDevices, KernSmooth, lazyeval, leaflet, lubridate, magrittr, maptools, methods, purrr, raster, Rcpp (≥ 0.12.7), rgeos, rlang, sf, sp, survival, stats, tibble, tidyr, utils, velox |
| LinkingTo: | Rcpp |
| Suggests: | adehabitatLT, bcpa, ctmm, devtools, move, moveHMM, spacetime, testthat, trajectories, knitr, Rdpack, rmarkdown |
| Published: | 2018-09-12 |
| Author: | Johannes Signer [aut, cre] |
| Maintainer: | Johannes Signer <jsigner at gwdg.de> |
| License: | GPL-3 |
| NeedsCompilation: | yes |
| Materials: | README NEWS |
| CRAN checks: | amt results |
| Reference manual: | amt.pdf |
| Vignettes: |
Getting started with amt Fitting a Step-Selection Function |
| Package source: | amt_<IP_ADDRESS>.tar.gz |
| Windows binaries: | r-devel: amt_<IP_ADDRESS>.zip, r-release: amt_<IP_ADDRESS>.zip, r-oldrel: amt_<IP_ADDRESS>.zip |
| OS X binaries: | r-release: amt_<IP_ADDRESS>.tgz, r-oldrel: amt_<IP_ADDRESS>.tgz |
| Old sources: | amt archive |
Please use the canonical form https://CRAN.R-project.org/package=amt to link to this page.


Complete all the fields below to sign up for the platform
More results with faster consultations.
Fast Alert Health Monitoring
The sign up procedure has been terminated: in your inbox you will find a welcome e-mail. Now you will be redirected to your private page.


Here’s a photo from last month’s photoshoot. We really had a great time and got a batch of really awesome shots for the new catalog.
Here’s a photo from last month’s photoshoot. We really had a great time and got a batch of really awesome shots for the new catalog.


Margery Hargest Jones - Songs Of Christmas - voice & piano
A collection of 47 Christmas favourites for medium voice with manageable piano accompaniments, guitar chords and background notes. Many songs are in .
http://shop.abrsm.org/shop/prod/Hargest-Jones-Margery-Songs-Of-Christmas-voice-piano/603688
Treatment for Herniated or Bulging Discs
Who Sings The Muppets 12 Days Of Christmas / towle sterling 12 ...
3 days ago . frank kelly 12 days of christmas plot of a christmas carol 2009 lyrics for ive been dreaming of a white christmas list of christmas songs from the .
http://jobosabe.com/profiles/blogs/who-sings-the-muppets-12-days-of-christmas-towle-sterling-12-days
Sterling Collectables | Wallace Past Editions |
2011 Wallace Songs of Christmas Sterling Ornament Code: wall-2411 . 2010 Wallace Song Sterling Ornament . 2009 Wallace Sleigh Bell Sterling Ornament .
http://www.sterlingcollectables.com/mm5/merchant.mvc?Screen=CTGY&Store_Code=scoll&Category_Code=wall
songs of christmas 2009 sterling Herniated or Bulging Discs
New Recordings
EARTH SONGS (choir and orchestra) FROM PENT-UP ACHING . "A Chatman Christmas" Choral music, Centrediscs, Toronto, fall 2009. LOVE CAME DOWN AT CHRISTMAS LITTLE CHILD IN A . STERLING BELLS CHRISTMAS JOY .
http://www.drstephenchatman.com/newrecordings.html
2012 Reed and Barton Silver Christmas Ornaments | Silver Superstore
Sterling silver. Christmas Ornament $91.95. 2012 Reed and Barton Francis I Songs of Christmas Sterling Silver Ornament · Francis I Songs of Christmas Sterling .
http://www.silversuperstore.com/ornaments/reed_barton_christmas.html
Reed and Barton Ornaments for sale affordable pricing !
X539 Francis I Songs of Christmas 10th Edition Sterling. Pattern: ORR R&B ORNAMENTS 2012. Type: ORNAMENTS Item #: 16197508. Your Price: $112.00 .
http://www.silverqueen.com/items/reed-and-barton-ornaments
Official Impairment Listing for Spinal Disorders
The Andy Williams Christmas Album - Wikipedia, the free ...
"A Song And A Christmas Tree" began as "The Twelve Days of Christmas", which was first . 2009, the list of the "Top 10 Holiday Songs (Since 2001)" places the Williams . Carols: The Stories Behind Twenty-Five Yuletide Favorites, Sterling .
http://en.wikipedia.org/wiki/The_Andy_Williams_Christmas_Album
- sign company real estate signs (narrowing of the spine)
Sterling and silverplated collectible Christmas ornaments - RM Sterling
RM Sterling ( toll free ) 1-800-851-2055. Visa/Mastercard . 2009 G.B. Snowflake (12th ed.).......$90 . 2010 Songs of Christmas (11th)....$100 1994 Star (2nd ed.) .
http://www.rmsterling.com/ornaments.htmlChristmas Ornaments, Holiday Ornaments | Ross-Simons
74 items . QuickView. Sterling Silver Reed & Barton 2012 "Francis 1st" - 10th Edition Songs of Christmas "Oh Tannenmaum" Ornament. Clearance: $84.99 .
http://www.ross-simons.com/collectibles/christmas-ornaments/products/navigate.jsp
Sterling Silver Christmas Ornaments made in the USA| Silver ...
2012 Reed and Barton Francis I Songs of Christmas Sterling Silver Ornament · Francis I Songs of Christmas Sterling Silver Christmas Ornament $91.95 .
http://www.silversuperstore.com/made-in-the-usa/ornaments/sterling-ornaments.html
Christmas Ornaments 2012 at Discount | Silver Superstore
2012 Reed and Barton Francis I Songs of Christmas Sterling Silver Christmas Ornament Francis I Songs of Christmas Sterling Silver Ornament by Reed & .
http://www.silversuperstore.com/christmas_ornaments.html
Medical-Vocational Allowance for Herniated Disc
At Christmas - Mick Sterling Presents
Classic Christmas songs performed in a refreshingly intimate way. At Christmas. Mick's 2009 release on the New Folk Records label is an intimate interpretation .
http://micksterlingpresents.com/Mick_Sterling_Presents/At_Christmas.html
Robert's Blog - Robert Sterling Music
5 days ago . There wasn't time to write a new show for 2012, but we suggested the idea of expanding The Christmas Post with three new songs.
http://robertsterlingmusic.com/blog/
Silver Christmas Ornaments at Discount
Silver Christmas ornaments for less! 2011 and . 2011 Reed and Barton Sterling Christmas Bell Sterling . 2011 Wallace Songs of Christmas Silver Ornament .
http://www.silversuperstore.com/2011-silver-christmas-ornaments.html
Appealing a Denial of Benefits
This Is Christmas Curt Smith Official Website
This Is Christmas. Curt Smith, co-founder of seminal music group Tears for Fears, released This Is Christmas, his first original holiday song, on November 29, .
http://curtsmithofficial.com/music/this-is-christmas/
20 of the Best Kids Christmas Books : The Childrens Book Review
Nov 12, 2009 . What holiday themes to expect: Carols, Christmas Spirit. TCBR analysis: A . Publisher: Sterling (October 6, 2009). What holiday themes to .
http://www.thechildrensbookreview.com/weblog/2009/11/20-of-the-best-kids-christmas-books.html


Econpile may rebound further, says RHB Retail Research
by theedgemarkets.comKUALA LUMPUR (Nov 4): RHB Retail Research said Econpile Holdings Bhd may rebound further after it tested 70 sen support in recent sessions.
In a trading stocks note today, the research house said as the stock rose above the 21-day SMA line, this indicates a positive sign.
“A positive bias may emerge above the 73.5 sen level, with an exit set below the 70 sen threshold.
“Towards the upside, the immediate resistance is at the 78.5 sen level, followed by the 82 sen threshold,” it said.


Welcome to Your personalized CTA App
Developer information:
The creative developer of this amazing app is Eram Ali.
She is a math and computer science major at the University of Illinois at Chicago.
she Loves to read and make amazing things.


property LayerStates: TLayerStates; // Read only
type TLayerState = (lsMouseLeft, lsMouseRight, lsMouseMiddle);
type TLayerStates = set of TLayerState;
Indicates the current state of the layer. At the moment, this property contains only information on pressed mouse buttons, but it will be expanded in future versions.


---
layout: home
author_profile: true
tagline: "Engineer, Neuroscientist & Data Scientist"
header:
overlay_image: /assets/images/header-DavidMatos-10x4.jpg
overlay_filter: 0.25 # same as adding an opacity of 0.5 to a black background
---
Hi there!
I am a researcher focused in signal processing and data analysis. My passion is using data to understand the world around me.


<index-sort-as>
The <index-sort-as> element specifies a sort phrase under which an index entry would be sorted.
Category: Indexing group elements


Salique is incredibly awesome, with a refreshingly clean design
We produce comprehensive mapping of consumers' relationships with communications across bought, owned & earned media based on bespoke insight. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam hendrerit lacus mattis orci fermentum mollis iaculis.


This script searches trade requests in game log file. The trade request is like "Hi, I'd like to buy your ...". It is not very accurate since there could be various tricky combinations, but could show you mostly correct list of trades you done in the past. Text file is parsed locally on your system and not offloaded to any servers.
File location: [game install folder]/logs/Client.txt


NbCalendarKitModule is a module that contains multiple useful components for building custom calendars.
NbCalendarKitModule


Is beautiful code possible? Thoughts from Alexander, Gabriel, and Dexter
I have recently be working on relearning software design patterns. This has included reading: “Head First Design Patterns” and Richard P. Gabriel’s “Patterns of Software”. In addition, I have been thinking and reading about aesthetics in software code. In particular, the paper “On the Embodied Aesthetics of Code” by Scott Dexter et. al. All this reading and coding at my day job has me thinking:)
-
Can the judgment of beauty be extended to other observers beyond myself - i.e. can beauty be objective?
-
Is beautiful code better than ugly code?
-
If so, then what is beautiful code?
According to Gabriel, beautiful code would be code that has what Christopher Alexander calls “the quality without a name”. This quality is something shared by all beautiful objects. These objects can be cities, houses, streets, or possibly as raised by Gabriel, software code. Alexander attempts to realign facts with value, instead of splitting them apart as has been in vogue since the 1800s.
A beautiful system is one with a whole that stems from its small parts. It is a system that has a stable dynamic harmony between its parts. It is living, being adapted, and modified by its inhabitants. Above all, its inhabitants feel the systems is habitable and beautiful.
The article “On the Embodied Aesthetics of Code” by Scott Dexter et. al. points out that in research studies, ugly code is more often attributed to code with bugs, and that one can pick out ugly code faster than one can judge some piece of code beautiful.
So if Alexander, Gabriel, and and Dexter are correct, then beauty can be objective and applied to code, for the purpose of helping to determine quality.
So, then what if we want beautiful code?
- What attributes would such code embody?
This is were pattern languages can come in to play. Gabriel uses his entire book to explore the overlap of Christopher Alexander’s work and that of software development. Through this he tries to define what attributes beautiful code should have.
He explains in his first few essays, which is as far as I have reached so far, that beautiful code must have Alexander’s “quality without a name”. This quality stems from: not over using abstractions, building from small components, and the use of pattern languages. Above all beautiful code is understandable to the point of allowing future extension and modification.
Abstractions are almost always touted as the goal of good software engineering. However, Gabriel points out, I believe correctly, that abstraction works as “compression”. By compression, here, he means, that each part of the abstraction is actually greater than its local meaning. This means that abstractions work because they are a type of analogy. Their meaning is derived from some prior knowledge.
Gabriel uses the common “stack” pattern as an example. Every CS major knows what a stack is and that if they see the word “stack” in a variable name, then they probably can assume that the author was referring to the common data structure.
Abstraction can fail for several reasons though:
-
The knowledge regarding the abstraction is not held by the current software editor.
-
The abstraction is too large, leaving room for ambiguity in its scope and side effects.
The first reason can be solved through education and the building of common pattern libraries. Hence the need for relearning design patterns.
Secondly, though, large abstractions are more dangerous and deserve more attention.
If an abstraction is large, it is probably not general enough to be in a common pattern language library.
Also, since no common knowledge exists, assumptions will be made or the code editor will have to read and understand the entire abstraction to use it.
This last point negates the entire purpose of an abstraction. Good abstractions can be extended and re-worked to save later coders time and reduce the risk of software bugs since the prior abstraction author should have already tested the component.

They have smaller scope, therefore are easier to test and communicate.
As QA Engineer I care about quality.
The idea that beauty can be an objective way to spot bugs in software is interesting to me.
Also, that pattern libraries can help to increase code habitability through creating beautiful software with the attribute of Alexander’s “quality without a name” is enticing.
In the end, if the judging of elegant code can be objective, then it can be taught, be a goal, and help to increase software quality.
With the help of common pattern languages, code can be better understood, leading to safer maintenance, and less bugs.
My current understanding is that beautiful code is habitable code, and habitable code, is code whose nuances and side-effects are easily seen and understood through the use of small common patterns.


Functions#
Plugin Implementation#
The function framework is used to implement SQL functions. Presto includes a
number of built-in functions. In order to implement new functions, you can
write a plugin that returns one more more functions from getFunctions()
:
public class ExampleFunctionsPlugin
implements Plugin
{
@Override
public Set<Class<?>> getFunctions()
{
return ImmutableSet.<Class<?>>builder()
.add(ExampleNullFunction.class)
.add(IsNullFunction.class)
.add(IsEqualOrNullFunction.class)
.add(ExampleStringFunction.class)
.add(ExampleAverageFunction.class)
.build();
}
}
Note that the ImmutableSet
class is a utility class from Guava.
The getFunctions()
method contains all of the classes for the functions
that we will implement below in this tutorial.
For a full example in the codebase, see either the presto-ml
module for machine
learning functions or the presto-teradata-functions
module for Teradata-compatible
functions, both in the root of the Presto source.
Scalar Function Implementation#
The function framework uses annotations to indicate relevant information
about functions, including name, description, return type and parameter
types. Below is a sample function which implements is_null
:
public class ExampleNullFunction
{
@ScalarFunction("is_null", calledOnNullInput = true)
@Description("Returns TRUE if the argument is NULL")
@SqlType(StandardTypes.BOOLEAN)
public static boolean isNull(@SqlNullable @SqlType(StandardTypes.VARCHAR) Slice string)
{
return (string == null);
}
}
The function is_null
takes a single VARCHAR
argument and returns a
BOOLEAN
indicating if the argument was NULL
. Note that the argument to
the function is of type Slice
. VARCHAR
uses Slice
, which is essentially
a wrapper around byte[]
, rather than String
for its native container type.
@SqlType
:The
@SqlType
annotation is used to declare the return type and the argument types. Note that the return type and arguments of the Java code must match the native container types of the corresponding annotations.@SqlNullable
:The
@SqlNullable
annotation indicates that the argument may beNULL
. Without this annotation the framework assumes that all functions returnNULL
if any of their arguments areNULL
. When working with aType
that has a primitive native container type, such asBigintType
, use the object wrapper for the native container type when using@SqlNullable
. The method must be annotated with@SqlNullable
if it can returnNULL
when the arguments are non-null.
Parametric Scalar Functions#
Scalar functions that have type parameters have some additional complexity. To make our previous example work with any type we need the following:
@ScalarFunction(name = "is_null", calledOnNullInput = true)
@Description("Returns TRUE if the argument is NULL")
public final class IsNullFunction
{
@TypeParameter("T")
@SqlType(StandardTypes.BOOLEAN)
public static boolean isNullSlice(@SqlNullable @SqlType("T") Slice value)
{
return (value == null);
}
@TypeParameter("T")
@SqlType(StandardTypes.BOOLEAN)
public static boolean isNullLong(@SqlNullable @SqlType("T") Long value)
{
return (value == null);
}
@TypeParameter("T")
@SqlType(StandardTypes.BOOLEAN)
public static boolean isNullDouble(@SqlNullable @SqlType("T") Double value)
{
return (value == null);
}
// ...and so on for each native container type
}
@TypeParameter
:The
@TypeParameter
annotation is used to declare a type parameter which can be used in the argument types@SqlType
annotation, or return type of the function. It can also be used to annotate a parameter of typeType
. At runtime, the engine will bind the concrete type to this parameter. Optionally, the type parameter can be constrained to descendants of a particular type by providing aboundedBy
type class to@TypeParameter
.@OperatorDependency
may be used to declare that an additional function for operating on the given type parameter is needed. For example, the following function will only bind to types which have an equals function defined:
@ScalarFunction(name = "is_equal_or_null", calledOnNullInput = true)
@Description("Returns TRUE if arguments are equal or both NULL")
public final class IsEqualOrNullFunction
{
@TypeParameter("T")
@SqlType(StandardTypes.BOOLEAN)
public static boolean isEqualOrNullSlice(
@OperatorDependency(operator = OperatorType.EQUAL, returnType = StandardTypes.BOOLEAN, argumentTypes = {"T", "T"}) MethodHandle equals,
@SqlNullable @SqlType("T") Slice value1,
@SqlNullable @SqlType("T") Slice value2)
{
if (value1 == null && value2 == null) {
return true;
}
if (value1 == null || value2 == null) {
return false;
}
return (boolean) equals.invokeExact(value1, value2);
}
// ...and so on for each native container type
}
Another Scalar Function Example#
The lowercaser
function takes a single VARCHAR
argument and returns a
VARCHAR
, which is the argument converted to lower case:
public class ExampleStringFunction
{
@ScalarFunction("lowercaser")
@Description("converts the string to alternating case")
@SqlType(StandardTypes.VARCHAR)
public static Slice lowercaser(@SqlType(StandardTypes.VARCHAR) Slice slice)
{
String argument = slice.toStringUtf8();
return Slices.utf8Slice(argument.toLowerCase());
}
}
Note that for most common string functions, including converting a string to
lower case, the Slice library also provides implementations that work directly
on the underlying byte[]
, which have much better performance. This function
has no @SqlNullable
annotations, meaning that if the argument is NULL
,
the result will automatically be NULL
(the function will not be called).
Aggregation Function Implementation#
Aggregation functions use a similar framework to scalar functions, but are a bit more complex.
AccumulatorState
:All aggregation functions accumulate input rows into a state object; this object must implement
AccumulatorState
. For simple aggregations, just extendAccumulatorState
into a new interface with the getters and setters you want, and the framework will generate all the implementations and serializers for you. If you need a more complex state object, you will need to implementAccumulatorStateFactory
andAccumulatorStateSerializer
and provide these via theAccumulatorStateMetadata
annotation.
The following code implements the aggregation function avg_double
which computes the
average of a DOUBLE
column:
@AggregationFunction("avg_double")
public class AverageAggregation
{
@InputFunction
public static void input(LongAndDoubleState state, @SqlType(StandardTypes.DOUBLE) double value)
{
state.setLong(state.getLong() + 1);
state.setDouble(state.getDouble() + value);
}
@CombineFunction
public static void combine(LongAndDoubleState state, LongAndDoubleState otherState)
{
state.setLong(state.getLong() + otherState.getLong());
state.setDouble(state.getDouble() + otherState.getDouble());
}
@OutputFunction(StandardTypes.DOUBLE)
public static void output(LongAndDoubleState state, BlockBuilder out)
{
long count = state.getLong();
if (count == 0) {
out.appendNull();
}
else {
double value = state.getDouble();
DOUBLE.writeDouble(out, value / count);
}
}
}
The average has two parts: the sum of the DOUBLE
in each row of the column
and the LONG
count of the number of rows seen. LongAndDoubleState
is an interface
which extends AccumulatorState
:
public interface LongAndDoubleState
extends AccumulatorState
{
long getLong();
void setLong(long value);
double getDouble();
void setDouble(double value);
}
As stated above, for simple AccumulatorState
objects, it is sufficient to
just to define the interface with the getters and setters, and the framework
will generate the implementation for you.
An in-depth look at the various annotations relevant to writing an aggregation function follows:
@InputFunction
:The
@InputFunction
annotation declares the function which accepts input rows and stores them in theAccumulatorState
. Similar to scalar functions you must annotate the arguments with@SqlType
. Note that, unlike in the above scalar example whereSlice
is used to holdVARCHAR
, the primitivedouble
type is used for the argument to input. In this example, the input function simply keeps track of the running count of rows (viasetLong()
) and the running sum (viasetDouble()
).@CombineFunction
:The
@CombineFunction
annotation declares the function used to combine two state objects. This function is used to merge all the partial aggregation states. It takes two state objects, and merges the results into the first one (in the above example, just by adding them together).@OutputFunction
:The
@OutputFunction
is the last function called when computing an aggregation. It takes the final state object (the result of merging all partial states) and writes the result to aBlockBuilder
.Where does serialization happen, and what is
GroupedAccumulatorState
?The
@InputFunction
is usually run on a different worker from the@CombineFunction
, so the state objects are serialized and transported between these workers by the aggregation framework.GroupedAccumulatorState
is used when performing aGROUP BY
aggregation, and an implementation will be automatically generated for you, if you don’t specify aAccumulatorStateFactory


Home
Welcome!
 We have many kinds of cake, fresh and delicious. You can order our cake at home or come to our shop at Mars! You can easily order the cake and enjoy our service at home!
 We have many kinds of cake, fresh and delicious. You can order our cake at home or come to our shop at Mars! You can easily order the cake and enjoy our service at home!


Phased Reopening
We continue to plan towards expanding the library services available to you. Our top priority, as always, is the health and safety of our patrons and staff. We will continue following the rulings and recommendations of our local, state and federal leadership throughout this process, working alongside health and safety officials and our colleagues to safely serve you. Based upon comments from the Governor and other officials, it seems that Long Island is close to reaching Phase 1 of the statewide reopening plan. However, while we we remain closed, please do not return library materials in our book drop, fines will not be assessed for overdue materials while the Library is closed. Please check this website for continued updates on the library’s status.


A simple example using css pseudo class transform: translate to change what content is displayed on page.


Configuration¶
generate_config generate all the configuration that can be used in learning and inference.
utils.generate_config(
drug_encoding,
target_encoding,
result_folder = "./result/",
input_dim_drug = 1024,
input_dim_protein = 8420,
hidden_dim_drug = 256,
hidden_dim_protein = 256,
cls_hidden_dims = [1024, 1024, 512],
mlp_hidden_dims_drug = [1024, 256, 64],
mlp_hidden_dims_target = [1024, 256, 64],
batch_size = 256,
train_epoch = 10,
test_every_X_epoch = 20,
LR = 1e-4,
transformer_emb_size_drug = 128,
transformer_intermediate_size_drug = 512,
transformer_num_attention_heads_drug = 8,
transformer_n_layer_drug = 8,
transformer_emb_size_target = 128,
transformer_intermediate_size_target = 512,
transformer_num_attention_heads_target = 8,
transformer_n_layer_target = 4,
transformer_dropout_rate = 0.1,
transformer_attention_probs_dropout = 0.1,
transformer_hidden_dropout_rate = 0.1,
mpnn_hidden_size = 50,
mpnn_depth = 3,
cnn_drug_filters = [32,64,96],
cnn_drug_kernels = [4,6,8],
cnn_target_filters = [32,64,96],
cnn_target_kernels = [4,8,12],
rnn_Use_GRU_LSTM_drug = 'GRU',
rnn_drug_hid_dim = 64,
rnn_drug_n_layers = 2,
rnn_drug_bidirectional = True,
rnn_Use_GRU_LSTM_target = 'GRU',
rnn_target_hid_dim = 64,
rnn_target_n_layers = 2,
rnn_target_bidirectional = True
)
drug_encoding (str) - Encoder mode for drug. It can be “transformer”, “MPNN”, “CNN”, “CNN_RNN” …,
target_encoding (str) - Encoder mode for protein. It can be “transformer”, “CNN”, “CNN_RNN” …,
input_dim_drug (int) - Dimension of input drug feature.
input_dim_protein (int) - Dimension of input protein feature.
hidden_dim_drug (int) - Dimension of hidden layer of drug feature.
hidden_dim_protein (int) - Dimension of hidden layer of protein feature.
batch_size (int) - batch size
train_epoch (int) - training epoch
test_every_X_epoch (int) - test every X epochs
LR (float) - Learning rate.
cls_hidden_dims (list of int) - hidden dimensions of classifier.
mlp_hidden_dims_drug (list of int) - hidden dimension of MLP when encoding drug.
mlp_hidden_dims_target (list of int) - hidden dimension of MLP when encoding protein.
transformer_emb_size_drug (int) - embedding size of transformer when encoding drug.
transformer_intermediate_size_drug (int) -
transformer_num_attention_heads_drug (int) -
transformer_n_layer_drug (int) -
transformer_emb_size_target (int) -
transformer_intermediate_size_target (int) -
transformer_num_attention_heads_target (int) -
transformer_n_layer_target (int) -
transformer_dropout_rate (float) -


Find your home. Adjust sliders to match your requirements and click 'Search' to view areas of the country that match your criteria. As you zoom in, you may have to click 'Search' again to view areas. Please allow a few moments for loading time.
Disclaimer: Due to size limitations, Northern & Southern Jutland are not included in this version of HomeLocator.
Close
Fine tune the sliders in each of the three categories below. Click 'Search' to see which areas of the country are most suitable for you and your interests. Please allow some moments for loading/rendering of data.
Categories:
Specify distance to critera.
Results:
Click on colored grid cell on map to see further information regarding selected area.
Legend:
100-80% 80-60% 60-40% 40-20% 20-0%


Projects
(current)
Team Members
Time
Logout
Projects
Add Project
Project Details
Please select a project from the list
Add New Task
×
Assigned Project:
Assigned Team Member:
Description
Save changes


Change Log¶
0.0.5¶
Application¶
- [Bug Fix] Using Flask’s web server for the Dashboard on a public route on a standalone server (–host <IP_ADDRESS>)
- [Bug Fix] Javascript error while loading dashboard.
- [Bug Fix] Pip install error (Log.txt FileNotFound)
- [New Feature] Basic ability to run Monte Carlo Simulation and view summarised results in reporting suite.
- [Update] Load scripts use multi-processing for forecast calculations when processing data file.
- [Update] Load scripts using batch process.
- [Update] Debug commandline argument for viewing logging output `–debug’.
- [Update] Use Chat Bot from commandline with -c flag. EXPERIMENTAL
- [Update] Recommendation generator takes into account forecasts
- [Update] Flask Blueprints used for reporting views.
Documentation¶
- [New] Wiki started on GitHub for more responsive updates to documentation including changes to source during development.
- [Update] Tutorial.
0.0.4¶
Release 0.0.4 has breaking API changes. Namespaces have changed in this release. All the modules previously in the “demand” package are now inside the “inventory” package. If you have been using the “model_inventory” module, then nothing has changed, there will not be any break in contracts.
Application¶
- [Update] Explicit internal and public API.
- [Update] Excess, shortages added to the UncertainDemand order_summary.
- [Update] Moved abc_xyz.py, analyse_uncertain_demand.py, economic_order_quantity.py and eoq.pyx from “demand” to “inventory” package
- [Update] “demand” package now contains: evolutionary_algorithms.py, forecast_demand.py and regression.py
- [Update] retail_price added to model_inventory.analyse_orders.
- [Update] backlog added to the data format for loading into the analysis.
- [Update] Unit Tests.
- [Update] Docstrings.
- [New Feature] Analytic Hierarchy Process.
- [New Feature] API supports Pandas DataFrame.
- [New Feature] Browser based reporting suite, with charts, data summaries and integrated chat bot.
- [New Feature] Dash Bot, a basic chat bot assistant for the data in the reporting suite. Query data using natural language.
- [New Feature] Command line interface for processing .csv to database, launching reports and chat bot.
- [New Feature] “Model_Demand” module containing simple exponential smoothing and holts trend corrected exponential smoothing.
- [New Feature] Summarise and filter your analysis.
- [New Feature] Holts Trend Corrected Exponential Smoothing Forecast and optimised variant (evolutionary algorithm for optimised alpha and gamma)
- [New Feature] Simple Exponential Smoothing (evolutionary algorithm for optimised alpha).
- [New Feature] Evolutionary Algorithms for Smoothing Level Constants (converges on better smoothing levels using genetic algorithm)
- [New Feature] SKU and inventory profile recommendations generator.
Documentation¶
- [New] Reporting Suite Walk Through.
- [Update] Tutorial.
- [Update] Quick Guide.
- [New] Declare public API explicitly. describe and document each module and function, give an example also add to website tutorial as Jupyter notebook.
- [New] Docker for supplychainpy quick guide.
- [New] Analytic Hierarchy Process quick guide.
- [New] Inventory Modeling.
- [New] Demand Planning with Pandas.
0.0.3¶
Application¶
- Compiled Cython (eoq and simulation modules) for OS X, Windows and Linux.
- Removed z_value, file_type, file_path and reorder_cost parameters from simulate.run_monte_carlo.
Documentation¶
- Update Quick Guide
0.0.2¶
Application¶
- Added monte carlo simulation and simulation summary using Cython optimisation.
- Added orders analysis optimisation, based on results of the monte carlo simulation.
- Added simulate module to api.
- Added weighted moving average forecast.
- Added moving average forecast.
- Added mean absolute deviation.
- Updated economic order quantity using Cython optimisation.
- Updated unit tests.
Documentation¶
- Updates Quick Guide.
- Updated Tutorial.
- Updated README.md
- Added Formulas and Equations.
- Updated data.csv.
0.0.1¶
Application¶
- Added inventory analysis for uncertain demand. Analyse orders from .csv, .txt or from dict.
- Added inventory analysis summary for uncertain demand. ABC XYZ, economic order quantity (EOQ), reorder level (ROL), demand variability and safety stock.
Documentation¶
- Added Quick Guide.
- Added Tutorial.
- Added Installation.
Options¶
Currently using the reporting suite feature, requires the command line. Using a nix or PowerShell console, the typical command issued for processing a file and generating a report would be:
$ supplychainpy <filename> -a -loc <absolute-path-to-current-directory> -l
The command line arguments can be viewed by using the –help command in the cli.
-l, –launch
- Launches supplychainpy reporting GUI for setting port and launching the default browser. The reporting suite is hosted inside the browser and defaults to port 5000. The GUI provides the opportunity to change the port if necessary. The -l flag is a boolean flag, and its inclusion is essential if the aim is to launch into the reporting suite.
-loc
- Flag for the aboslute path to the current directory. The path is required to locate a current reporting.db or a store as the new location in the settings.
-a, –analyse
Initiates the analyisis of the file name supplied as the first argument directly after the supplychainpy command e.g.:
$ supplychainpy <filename> -a -loc <absolute-path-to-current-directory> -l
-lx, –launch-console
- Launches supplychainpy reporting on the default port, without GUI interface. Uses default port (5000) unless another port is specified. Appropriate for running the reports on a sever. Currently, this is only for testing. The Werkzeug web server that supplied with flask serves the pages for the reports. Werkzeug is not a production web server. It is sufficient as a local web server for the reporting application on a client system. In the coming releases deployment using a more robust web server such as Nginx or Gunicorn will be documented for Server type implementation.
-cur
- The flag Sets the currency for the analysis and should match the raw data. IMPORTANT: Currency conversion does not occur by setting this flag. The default currency is US Dollars (USD).
–host
- Sets the host for the server (defaults <IP_ADDRESS>).
–debug
- Runs in debug mode.
-p, –port
- Specify Port to use for local server e.g. 8080 (default: 5000).
-c
- Enter chat mode with the Dash bot from the command line.


Rules
Using the various rules, the developer can limit the user interactions.
In this example you won't be able to select the first root node, all nodes are renamable, but you can only create new items inside folders. You can drag folders around, but not the root nodes. While dragging, you won't be able to place the dragged item inside the second root node (you can only initiate the drag using the left mouse button). There is also one foreign item, that can be dragged onto the tree, but only on the second root node.
$(function () { $("#demo1").tree({ // Data configuration omitted rules : { clickable : [ "root2", "folder" ], deletable : [ "root2", "folder" ], renameable : "all", creatable : [ "folder" ], draggable : [ "folder" ], dragrules : [ "folder * folder", "folder inside root", "tree-drop * folder" ], drag_button : "left", droppable : [ "tree-drop" ] } }); });
Metadata
Metadata allows you to store the node type in a javascript object, passed as an attribute to each node. You can also store any data you need.
Combined with rules.use_inline metadata allows you to set per-node rules - clickable, renamable, etc. (You can also use three new rules: valid_children, max_depth and max_children)
This is the previous example, but with metadata added. You won't be able to drag the 'Child node 2' node, although its type is "folder". It may also contain only one node, and that node won't be allowed to have children.
$(function () { $("#demo2").tree({ data : { type : "json", json : [ { attributes: { id : "pjson1_1", rel : "root" }, state: "open", data: "Root node 1", children : [ { attributes: { id : "pjson1_2", rel : "folder" }, data: { title : "Custom icon", icon : "../media/images/ok.png" } }, { attributes: { id : "pjson1_3", rel : "folder", mdata : "{ draggable : false, max_children : 1, max_depth : 1 }" }, data: "Child node 2" }, { attributes: { id : "pjson1_4", rel : "folder" }, data: "Some other child node" } ]}, { attributes: { id : "pjson1_5", rel : "root2" }, data: "Root node 2" } ] }, rules : { metadata : "mdata", use_inline : true, clickable : [ "root2", "folder" ], deletable : "none", renameable : "all", creatable : [ "folder" ], draggable : [ "folder" ], dragrules : [ "folder * folder", "folder inside root", "tree-drop inside root2" ], drag_button : "left", droppable : [ "tree-drop" ] } }); });
Cookies
jsTree can save the user's current view in a cookie - for more on the cookie options - check the documentation. To see it in action - make a selection (or open/close a node) and refresh the page.
$(function () { $("#demo3").tree({ // data configuration omitted cookies : { prefix : "tree1", opts : { path : '/' } } }); });
Rollback
Rollbacks are good to use when you need to do some async calls and then maybe revert the tree to a previous state (for example, if the server operation failed).
$(function () { $("#demo4").tree({ // data configuration omitted callback : { onrename : function (n,l,tree_ref,rollback) { tree_ref.lock(true); setTimeout(function () { $.tree_rollback(rollback); tree_ref.lock(false); },1000); } } }); });
Search
You can pass the search function a string, and the nodes in the tree containing that string will have the class "search" applied to them. If async is used, a request is made to the server (data.url) with the GET/POST (according to data.method config) param "search" filled with the user search string - the expected response is a JSON array of node ids which need to be opened in order to get to the search results.
// Search $.tree_reference('demo5').search('other'); // Clear search $.tree_reference('demo5').search('');
Context menu
You can modify the functions shown in the context menu or disable it altogether (just set ui.context to false. In this example the context menu is be replaced.
$(function () { $("#demo6").tree({ // data config omitted ui : { context : [ { id : "ok", label : "test entry", icon : "../media/images/ok.png", visible : function (NODE, TREE_OBJ) { // return -1 for not visible if(NODE.attr("id") == "pjson5_2") return -1; // return false for disabled if(NODE.attr("id") == "pjson5_3") return false; // return true for visible and clickable return true; }, action : function (NODE, TREE_OBJ) { // Just a demo of the arguments alert('"' + NODE.children("a").text() + '" from "' + TREE_OBJ.container.attr("id") + '"'); } } ] } }); });


val placeOfDeath: String
place where the person died. This is optional and can be left blank (for example, if the person is currently alive).
placeOfDeath
- place where the person died. This is optional and can be left blank (for
example, if the person is currently alive).


@Exported public interface OperatingSystemMXBean extends OperatingSystemMXBean
The OperatingSystemMXBean object returned by
ManagementFactory.getOperatingSystemMXBean()
is an instance of the implementation class of this interface
or UnixOperatingSystemMXBean
interface depending on
its underlying operating system.
| Modifier and Type | Method and Description |
|---|---|
long |
getCommittedVirtualMemorySize()
Returns the amount of virtual memory that is guaranteed to
be available to the running process in bytes,
or -1 if this operation is not supported.
|
long |
getFreePhysicalMemorySize()
Returns the amount of free physical memory in bytes.
|
long |
getFreeSwapSpaceSize()
Returns the amount of free swap space in bytes.
|
double |
getProcessCpuLoad()
Returns the "recent cpu usage" for the Java Virtual Machine process.
|
long |
getProcessCpuTime()
Returns the CPU time used by the process on which the Java
virtual machine is running in nanoseconds.
|
double |
getSystemCpuLoad()
Returns the "recent cpu usage" for the whole system.
|
long |
getTotalPhysicalMemorySize()
Returns the total amount of physical memory in bytes.
|
long |
getTotalSwapSpaceSize()
Returns the total amount of swap space in bytes.
|
getArch, getAvailableProcessors, getName, getSystemLoadAverage, getVersion
getObjectName
long getCommittedVirtualMemorySize()
long getTotalSwapSpaceSize()
long getFreeSwapSpaceSize()
long getProcessCpuTime()
long getFreePhysicalMemorySize()
long getTotalPhysicalMemorySize()
double getSystemCpuLoad()
double getProcessCpuLoad()
Copyright © 2003, 2019, Oracle and/or its affiliates. All rights reserved.