The institute takes pride in its exceptional faculty who are authorities in industry research, consultancy and academics. The composition of the faculty is a healthy mix of well respected academicians and business executives. At the TISS, we boast of one of the highest faculty to student ratios in the country. The faculty has also published articles in leading academic & business journels like the South Asian Journal of Management, the Journal of Indian Psychology, the Indian Journal of Labour Economics and the Economic & Political weekly.
Core Faculty
- Dr. Sharit K. Bhowmik Professor and Dean M.A.(Mumbai), Ph.D(Delhi)
- Dr. Sasmita Palo Associate Professor & Chairperson M.A., LL.B, Ph.D(Behrampur)
- Dr. D.K. Srivastava Professor M.Com, D.Phil(Allahabad), FDPM(IIM-A)
- Dr. A.M. Sharma TISCO Chair Professor
- Dr. P.C. Saxena Garware Chair Professor
- Mr. Noel Machado Assistant Professor M.A.(Mumbai)
- Dr. E. Toppo Associate Professor M.A., Ph.D(Poona)
- Dr. Sarla K. Rao Assistant Professor M.B.A., M.Phil(Andhra)
- Mr. P. Vijaykumar Assistant Professor M.A (Calicut), M.Phil(Bharathiar)
- Dr. Zubin R. Mulla Assistant Professor B.E(Poona), P.G.D.B.M.(XLRI), FPM,(XLRI)
Adjunct Faculty
- Mr. V S Patwardhan Former VP, HR Asian Paints
- Dr. Akash Khurana Vice Chairman, Nimbus Communications
- Mr. V R Narsimhan Chief Compliance Officer, Kotak Mahindra
- Mr. Rajen Mehrotra Chief Knowledge Officer, ACC Limited
- Dr. L R Dwivedi Professor, Nursee Monjee Institute of Management Studies
- Mr.Ashutosh Ghani Channel Programs Manager, APAC Region Intel India
- Mr.Ninan Eapen Chundamannil Strategic Relations Manager, Intel India
- Mr. P.Vijayan Head HR, CHEP
- Mr.Anirudha Deshmukh General Manager, HR Asian Paints
- Prof. K.V. Ganapthy Corporate Trainer & OD Specialist
- Mr.Amitabh Sengupta General Manager, HR BPCL, Refinery


introduced pieces:
A
A,B
A,B,C
first half
any current
last half
highest current
any
width
2
3
4
5
6
7
8
height
2
3
4
5
6
7
8
last letter:
wrap
plateau


class: center, middle # IEMS 5780
Building and Deploying Scalable
Machine Learning Services ### Lecture 1 - Course Introduction #### Albert Au Yeung
6th September, 2019 --- # Agenda ### Course Administration * Course details * Course schedule * Assessment Schemes * Policies and Rules ### Course Content Overview * Machine Learning * Scalable Network Applications --- # Course Instructors ### **Lecturer**: Albert Au Yeung * Email<EMAIL_ADDRESS>* For lecture content, materials, details of assignments, reference materials, etc. ### **TA**: TBC * Email: TBC * Contact the TA if you need specific help when working on your assignments --- # About Me * BEng in IE, MPhil in CSE * PhD in Computer Science (University of Southampton, UK) * AI Technical Manager at Wisers AI Lab (https://www.wisers.ai) * Was machine learning engineer & researcher at NTT, ASTRI and Huawei * [https://www.linkedin.com/in/albert-au-yeung/](https://www.linkedin.com/in/albert-au-yeung/) --- # Lectures ### Venue & Time * Lee Shau Kee Architecture Building (ARC) **G03** * Thursday 7:00pm – 10:00pm * **Lecture dates (13 lectures)**: + Sep 6, 13, 20, 27 + Oct 4, 11, 18, 25 + Nov 1, 8, 15, 22 + Dec 13 (Final Examination) * Refer to the [course Website](http://iems5780.albertauyeung.com/) for the most up-to-date schedule of the course --- # Topics * This course will be divided roughly into two parts * **Part 1 - Machine Learning**: - Lecture 2: Machine learning basics - Lectures 3-4: Text classification - Lectures 5: Recommender Systems - Lecture 6: Computer Vision * **Part 2 - Network Applications**: - Lecture 7: Network Programming - Lectures 8-9: Concurrent Programming - Lecture 10: Web Applications - Lecture 11: Asynchronous Tasks and Message Queues - Lecture 12: Deploying Machine Learning Applications --- # Assessment Scheme ## IEMS 5780 * **10%** - Attendance (Lecture 2 to Lecture 12) * **60%** - Programming Assignments * **30%** - Final Examination (Written & Close books/notes) --- # Programming Assignments * A total of **4** programming assignments * All should be finished using the [Python programming language](https://www.python.org/) * Late submission will **NOT** be marked * Topics of the assignments: - machine learning problems - network programming - Web application development * We focus on building the **backend** applications, but we still need some **UI**, so we will use **bots** on [Telegram](https://telegram.org/blog/bot-revolution) --- # What should you expect? ### Take this course if you: * Have background in computer networks and related concepts * Have basic understanding or willing to learn the Python Programming Language * Would like to challenge yourself with interesting programming and system design problems --- # Approach of this Course * Machine learning is a **huge** topic, to be good at machine learning, you will have to have good foundations in - Statistics - Linear algebra - Calculus - Probability theory - Signal processing - ... * However, this is NOT a course that follow the usual path of introduction to machine learning --- # Approach of this Course * In this course, we take a **hacker's** approach: to learn how to use machine learning in a practical way, and to focus on how to make machine learning available to other people/systems * **Focus** of this course: * The workflow/pipeline of machine learning projects (from data collection to application deployment) * Building and deploying scalable network applications * What you will **learn** after taking this course? * Working on common machine learning tasks * Network programming and concurrent programming in Python * How to build a distributed and scalable network application * How to serve machine learning models --- # Some Rules ### What you should do in this course? * Attend the lectures, and raise questions whenever you have any * Seek help as **early** as possible (e.g. if you have difficulties in picking up Python programming, or if you cannot set up the development environment) * Feel free to make **suggestions** to the course and/or lectures * Do your own assignments, and do NOT make your work publicly available before the deadline * **Actively learn** relevant skills and knowledge outside the classroom --- # Honesty in Academic Work * **Zero tolerance** on cheating and plagiarism * Read: [http://www.cuhk.edu.hk/policy/academichonesty/](http://www.cuhk.edu.hk/policy/academichonesty/) * Cite references whenever you use materials from any other sources * It will be considered **plagiarism** no matter you copy other’s work or allow others to copy your work --- # Online Resources * Assignments will be released and collected on the CUHK E-Learning System: [https://elearn.cuhk.edu.hk/](https://elearn.cuhk.edu.hk/) * You will submit your assignments there --- # Online Resources * Course Website: [http://iems5780.albertauyeung.com/](http://iems5780.albertauyeung.com/) * **Lecture slides**, **assignments**, **references** will be available there
--- # Online Resources * For more convenient communication among us and discussions among yourselves, we will use Slack in this course: [https://iems5780-1920t1.slack.com/](https://iems5780-1920t1.slack.com/) * Sign up for an account on slack and join the above team * NOTE: **DO NOT** post any solution of assignments on Slack or any other public channels
--- # Using Cloud Services * In this course, we will use Python and its various packages for machine learning and networking * In many cases, things will work on Windows / Mac OS / Linux * However, you are advanced to prepare a **Linux environment** (preferrably **Ubuntu**) * You can get a virtual machine running Ubuntu on: - Amazon AWS ([https://aws.amazon.com/free/](https://aws.amazon.com/free/)) - Google Cloud ([https://cloud.google.com/free/](https://cloud.google.com/free/)) --- class: center, middle # Course Overview --- class: center, middle # Machine Learning --- class: equal-split # Machine Learning .column-left[ * A computer program generates an input given and output, given some **pre-defined function(s)** * ML aims at **learning** a function that maps the inputs to the outputs * Instead of having a programmer writing down the **logic**, we let the computer **learn** from the data * Given historical data, we train a **model** to generate predictions on **future or unseen** inputs ] .column-right[
] --- # Machine Learning * Given some input `\(X\)` and ouptut `\(y\)`, find a function `\(F(X)\)` that maps `\(X\)` to `\(y\)`. * Example: given (
location, size
) (`\(X\)`), predict the
price
of a house (`\(y\)`). * Another example: give (
previously watched movies
) (`\(X\)`), predict the
next movie(s) that will be watched
(`\(y\)`).
--- # Example: Hand-written Digit Recognition * Recognize hand-written digits using a machine learning approach
(one of the first widely used ML systems)
* References: - [Reading handwritten digits: a ZIP code recognition system (PDF)](http://yann.lecun.com/exdb/publis/pdf/matan-92.pdf) - [The MNIST Dataset](http://yann.lecun.com/exdb/mnist/) --- class: equal-split # Example: Recommender Systems * Learn to **recommend** movies or books to users based on their **past purchase and browsing behaviour** * The [Netflix Prize](https://en.wikipedia.org/wiki/Netflix_Prize): a competition to build a movie recommender system for Netflix * The winning algorithm: [BellKor's Pragmatic Chaos](https://www.netflixprize.com/assets/GrandPrize2009_BPC_BellKor.pdf)
--- # Example: Face Detection / Recognition * Learn to detect **human faces** in an image or a video stream * Recognize the persons with the faces * Example: Microsoft's [Face API](https://docs.microsoft.com/en-us/azure/cognitive-services/face/overview)
--- # Example: Machine Translation * [Statistical machine translation (SMT)](https://en.wikipedia.org/wiki/Statistical_machine_translation) or [Neural machine translation (NMT)](https://en.wikipedia.org/wiki/Neural_machine_translation) learn to translate sentences from one language into another language by analysing parallel text corpora * Google's Neural Machine Tranlsation: [https://ai.google/research/pubs/pub45610](https://ai.google/research/pubs/pub45610)
--- # The "Kaggle" Way of Machine Learning * [Kaggle](https://www.kaggle.com/): a Website that host **machine learning competitions** * You train a machine learning model, and generate predictions on the testing data * The models that achieve the best performance on the leader board will win the prizes * Everything is **offline**
--- # Machine Learning Applications * In practice, generating predictions is only a **small part** of a machine learning project * Consider a system that uses machine learning to recognize hand-written letters
* Ref: Uber's Customer Obssession Ticket Assistant [https://eng.uber.com/cota/](https://eng.uber.com/cota/) --- # Common ML Systems Workflow * There are several common **workflows** for machine learning systems 1. Train offline ➤ Predict offline ➤ Store predictions in DB 2. Train offline ➤ Embed model in a device ➤ Predict online 3. Train offline ➤ Make model available as a service ➤ Predict online * Notes: - **Offline**
separate from a production system; does not have to be completed in real time - **Online**
part of a production system; perform tasks in real time --- # Common ML Systems Workflow (1) * Train offline ➤ Predict offline ➤ Store predictions in DB * Example: **Recommender systems** - A model is trained **offline** - For each user, generate (pre-compute) a list of recommended items, store in **database** - When the user visits the Website, return the list of items
--- class: equal-split # Common ML Systems Workflow (2) .column-left[ * Train offline ➤ Embed model in a device ➤ Predict online * Example: **Object detection using a drone** - A model is trained offline - The model together with other processing logic are downloaded to the drone's computer - The drone detects objects while it is in operation ] .column-right[
] --- # Common ML Systems Workflow (3) * Train offline ➤ Make model available as a service ➤ Predict online * Example: **Spam E-mail detection** - A classifier is trained offline with spam and non-span emails - Deployed as a service to serve users or other components in the system
--- # Common ML Systems Workflow * In (2) and (3), we need to think about how to **deploy** a machine learning model * Definition of **deploy**: - To place some resources into a position so as to be ready to for action or use * In this course, we will focus on **Use Case (3)** - How to make machine learning models **available** to other users/systems? - How to serve machine learning models over the **network** - How to deploy our models to serve **many** concurrent users? --- # Challenges in Deploying Machine Learning Models - Requirement of **computing resources** (RAM, CPU/GPU) - **Time** required to generate a prediction - How to **update** the model - How to serve many **concurrent requests** - How to **monitor** model performance - ... --- class: middle, center # Computer Network --- # Computer Network * A network that allows computers to perform data communication with one another
* The Internet is **a network of networks**. ([Global Internet Traffic](https://en.wikipedia.org/wiki/Internet_traffic#Global_Internet_traffic)) --- # Data Communication * Exchange of data between two devices using some form of transmission medium * A simplified communication model:
* When performing communication, we need **protocols**: rules that govern how data is transmitted in this system --- # Protocols * **Network protocols** defines how computers talk to each other, including: * How to start a communication * The format of a message * What should be done when the data is corrupted during transmission * What should be done when the connection is broken during transmission * ... * Examples: **TCP/IP**, **HTTP**, **FTP** * Internet protocols are specified in documents called [**Requests for Comment (RFC)**](https://en.wikipedia.org/wiki/Request_for_Comments), such as: * [RFC 793 - Transmission Control Protocol (TCP)](https://tools.ietf.org/html/rfc793) * [RFC 1180 - A TCP/IP Tutorial](https://tools.ietf.org/html/rfc1180) * [RFC 6455 - The WebSocket Protocol](https://tools.ietf.org/html/rfc6455) --- # Computer Network ### When we have many computers that want to talk to one another, point-to-point links become not practical, especially when the distance is too far
--- # The History of Internet in 3 Minutes
--- # Problems and Challenges in Computer Networking ### Challenges in Networking: * How can data be transmitted from one node to another through the network?
**(e.g. routing/switching)** * How can we address the computers?
**(e.g. IP Address)** * How can we identify which applications on the computers the data should be delivered to?
**(port and socket)** * How to handle error or missing data?
**(e.g. the TCP protocol)** * What if a large amount of data is transmitted at the same time? * How to **coordinate** a large number of applications over a network? --- # Applications ### Common Applications on the Internet * The World Wide Web (Web servers and browsers) * File transfer (FTP servers and clients) * Instant messaging & video conferencing (e.g. Skype, Whatsapp, Wechat) * Peer-to-peer file sharing * Video and audio streaming * Cloud storage (Sync files across machines) * ... --- # Example 1: The World Wide Web
--- # Example 2: Instant Messaging & Video Conferencing
--- # Example 3: P2P File Sharing
--- # Major Topics * **Network Programming** - How to make two or more computers talk to each other over a network? - How to use common protocols to send and receive data?
* **Concurrent Programming** - How to simultaneously carry out different task in a program
* **Scalable architecture** - How to make a system scalable when traffic increases and the system becomes more complex? - How to make a network application robust and efficient? --- # Network Programming * Enable **communications** among computers using some protocols * Our focus: * TCP/IP (TCP & UDP) * HTTP, Websockets * Develop your own servers and clients in Python * Data format for exchanging information (e.g. JSON, XML) * Serving **machine learning models** in network applications --- class: split # Concurrent Programming .column-left[ * How to perform tasks in parallel * Our focus: * Threading and multiprocessing * Limitations of multithreading in Python * Aysnchronous model * Blocking and non-blocking calls ] .column-right[
The Asynchronous model (Ref: [Twisted Introduction - Part 1](http://krondo.com/in-which-we-begin-at-the-beginning/)) ] --- # Scalable Architecture * How to design the architecture of a network application? * How to coordinate different components in system when complexity increases * E.g. Using asynchronous tasks and message queues, caches, databases
--- class: split # Challenges in Network and Concurrent Programming .column-left[ ### The Dining Philosophers Problem * Details: [Dining philosophers problem - Wikipedia](https://en.wikipedia.org/wiki/Dining_philosophers_problem) * Five philosophers sit at a round table with bowls of spaghetti. Forks are placed between each pair of adjacent philosophers. * Each philosopher must alternately think and eat. * A philosopher can only eat when he has both left and right forks. * Each fork can be held by only one philosopher. * A proper solution should never arrive in a **deadlock** situation. ] .column-right[
] --- # Challenges in Network and Concurrent Programming ### The CAP Theorem * Details: [CAP theorem - Wikipedia](https://en.wikipedia.org/wiki/CAP_theorem) * In a distributed system, three properties are of particular interests: * C – Consistency * A – Availability * P – Partition Tolerance * Recommended Reading: Kaushik Sathupadi. ‘A plain english introduction to CAP Theorem’ [http://ksat.me/a-plain-english-introduction-to-cap-theorem/](http://ksat.me/a-plain-english-introduction-to-cap-theorem/) --- # The CAP Theorem * **C: (Atomic) Consistency** * A ‘read’ to the system will always reflect the latest ‘write’ action * All node sees the same data at the same time * **A: Availability** * Every request received by a non-failing node must result in a response (the system is continuously available to the clients) * It does not guarantee that the response is given in a specific period of time, however there should be a response for ever request * **P: Partition Tolerance** * A distributed system has multiple nodes, partition tolerance requires that the system continues to operate even when the network fails --- class: split # The CAP Theorem .column-left[ * Also known as Brewer’s Theorem * It states that it is **impossible** for a distributed system to have **all 3 properties** at the same time. * Reference: Seth Gilbert and Nancy Lynch, “Brewer's conjecture and the feasibility of consistent, available, partition-tolerant web services”, ACM SIGACT News, Volume 33 Issue 2 (2002), pg. 51-59. ] .column-right[
] --- # The CAP Theorem ### Choosing between consistency and availability: * **C + P** * When network is partitioned, partitioned nodes will not be able to return a response * Clients receive timeout or error * Preferred when **strict atom consistency is needed** (e.g. e-commerce site) * **A + P** * A partitioned node will return the most recent version of the data it has, not guaranteed to be the same as the latest version * Opt for this if **availability** is important, and there is flexibility in returning the latest data to the clients --- class: center, middle # Python Programming --- # What is Python? * An high-level interpreted programming language * Created by [Guido van Rossum](https://en.wikipedia.org/wiki/Guido_van_Rossum) in 1991 * Emphasizes code readability and flexibility (See [Python's Design Philosophy](http://python-history.blogspot.hk/2009/01/pythons-design-philosophy.html)) * Current stable versions: Python 2.7 (Version 2), and Python 3.6 (Version 3)
--- # Programming in Python * Hello World in Python ```python $ python3 Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> print("Hello World!") Hello World! >>> ``` * Type `python3` (or simply `python`) to invoke the Python interpreter * `print()` will output the arguments to standard output --- # Programming in Python * Python programs (or scripts) are commonly named using the `.py` extension, and are called **modules** * A "hello world" script `hello.py`: ```python print("Hellow World!") ``` * Executing the script: ```bash $ python3 hello.py Hello World! $ ``` --- # What do people use Python for? ### Python is a general purpose programming language and are widely used in different domains. (See [Python Success Stories](https://www.python.org/about/success/)) * Web and Internet applications backend (e.g. Youtube, Dropbox, Reddit) * Scientific computing * Data science and machine learning (e.g. Tensorflow, Keras) * Data visualization * Financial Analysis * ... --- # Installing Python * Available on Linux / Mac / Windows (https://www.python.org/downloads/) * Note: Download **Python 3.6** for this course * IDEs recommended for Python programming: 1. [JetBrains PyCharm](https://www.jetbrains.com/pycharm/) (Community Edition is free) 2. [MS Visual Studio Code](https://code.visualstudio.com/) (Free and open source) * Python comes with some standard modules, other modules can be installed using `pip` (https://pypi.python.org/pypi). For example: ```bash $ python3 -m pip install requests ``` --- # Python Basics ```python # Everything after a `#` is comment # import modules using the import keyword import math # define functions using def def power_three(x): return math.pow(x, 3) if __name__ == "__main__": print(power_three(10)) # Executing this script prints 1000.0 ``` * In Python, **indentation** is important: the statements in the same logical block should have the **same** indentation. * Set your editor to use SPACES instead of TAB for indentation. * You **do not** have to declare a variable before using it --- # Python Basics ```python # if-then-else statements if x == 0: print("Zero!") elif x > 0: print("Larger than Zero!") else: print("Less than Zero") # while loop x = 0 while x < 10: x += 1 # for loop for x in range(10): print(x) ``` --- # Python Data Structures ### Lists * Lists are like arrays in other languages, but are more flexible ```python cities = ["Hong Kong", "Macau", "Taipei", "Beijing"] print(cities[0]) # prints "Hong Kong" print(cities[2]) # prints "Taipei" print(cities[-1]) # prints "Beijing" print(len(cities)) # prints 4 print(cities[1:3]) # prints ["Macau", "Taipei"] print(cities[:3]) # prints ["Hong Kong", "Macau", "Taipei"] print(cities[2:]) # prints ["Taipei", "Beijing"] print(cities[::-1]) # prints ["Beijing", "Taipei", "Macau", "Hong Kong"] ``` --- # Python Data Structures ### Using lists in for loops * Lists are iterables, meaning that you can loop through each of its values as follows: ```python numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] sum = 0 for n in numbers: sum += n print(sum) # prints 55 ``` --- # Python Data Structures ### List methods * List objects have a number of using methods: ```python x = [1, 2, 3] x.append(4) # x becomes [1, 2, 3, 4] x.insert(0, 0) # x becomes [0, 1, 2, 3] x.extend([4, 5]) # x becomes [1, 2, 3, 4, 5] x.sort(reverse=True) # x becomes [3, 2, 1] x.index(2) # this returns 1, the index of the element 2 ``` * For a comprehensive list of methods, see https://docs.python.org/3/tutorial/datastructures.html --- # Python Data Structures ### Dictionaries * Another commonly used data structure in Python is the **dictionary** * It can be used to store **key-value pairs** (Similar to the "associative arrays" in PHP) * Keys must be immutable types (e.g. Lists cannot be used as keys) ```python exam_scores = {"John": 70, "Mary": 80} print(exam_scores["John"]) # prints 70 print(exam_scores["Mary"]) # prints 80 print(list(exam_scores.keys())) # prints ["John", "Mary"] print(list(exam_scores.values())) # prints [70, 80] ``` --- # Python Data Structures * **Iterating over key-value pairs in a dictionary** * Given that a dictionary is used to store key-value pairs, you can iterate over all key-value pairs using a loop as follows: ```python exam_scores = {"John": 70, "Mary": 80} # exam_scores.items() actually returns [("John", 70), ("Mary", 80)] # which is a list of 2-tuples for name, score in exam_scores.items(): print("{:s} scores {:d} in the exam.".format(name, score)) ``` * In the above `print` statement, `{:s}` is a string placeholder, `{:d}` is an integer placeholder. * More can be found at https://docs.python.org/3/tutorial/datastructures.html --- # Files in Python ```python f = open("file.txt", "r") # open a file in read mode for line in f: print(line) f.close() # Always close the file after use ``` * In practice, it is better to specify the encoding of the file content ```python f = open("file.txt", "r", encoding="utf-8") for line in f: print(line) f.close() ``` --- # Python Modules * A **module** in Python is a file containing Python definitions and statements * Put your source codes in different modules to avoid having a huge single `.py` file * You can **import** class, functions and variables from other modules ```python # This is in my_functions.py def factorial(n): f = 1 for i in range(n): f *= i + 1 return f # In another file, e.g. main.py from my_functions import factorial print(factorial(5)) # prints 120 ``` * Reference: https://docs.python.org/3/tutorial/modules.html --- # More about Python Programming ### Documentations and Tutorials * Read about the history of Python at https://en.wikipedia.org/wiki/Python_(programming_language) * Read Python tutorials at https://docs.python.org/3/tutorial/ * Consult the documentation at https://docs.python.org/3/ --- # More about Python Programming ### Coding Convention and Styles * Python's development is based on the [Python Enhancement Proposals (PEP)](https://www.python.org/dev/peps/), which is a list of proposals of new features * [PEP 8](https://www.python.org/dev/peps/pep-0008/) describes coding conventions or style guides for Python programming. ### Others * Explore Python packages and projects online:
https://github.com/vinta/awesome-python --- # Using Virtualenv ### Dependencies * When working on a Python project, it is common that you will use modules outside of the standard library (e.g. requests, BeautifulSoup, numpy, pandas) * Different projects may have different dependencies (on **different modules**, or even **different versions** of the modules) ### Project isolation * [Virtualenv](https://virtualenv.pypa.io/en/stable/) is a software that allows you to create an isolated environment for a project * Install virtualenv by: ```bash $ python3 -m pip install virtualenv ``` --- # Using Virtualenv * Once installed, you can create a virtual environment using the following command (`venv` is the name of the environment, which you can choose as you like): ```bash $ virtualenv venv ``` * To activate the environemnt, use the following command: ```bash $ source venv/bin/activate ``` * Once you see the `(venv)` prefix, it means that the virtual environment is successfully activated. * From this point onwards, all `pip install` command will only install packages **within this environment** * To exit the environment, type **`deactivate`** --- class: center, middle # End of Lecture 1


Italy Announced a National State of Emergency due to the Catastrophic Flood in Venice
The Italian government announced a national state of emergency on Thursday evening due to the catastrophic flood in Venice, world agencies have reported.
Floodwater levels in Venice reached the highest level in more than 50 years, DW reported.
Yesterday, Italian Prime Minister Giuseppe Conte was in the affected city. Conte also tweeted that the Italian Cabinet approved €20 million ($22 million) to help the city recover from the floods.
Today in Venice, the weather is good again, and the 50,000 residents of the historic centre have used it to take their possessions and goods out and try to dry their homes and shops.
The floodwater level registered in the city today is 1.13 meters. On Tuesday night, at the peak of the flood, it was 1.87 meters.
A special commission for Venice will meet on November 26 to discuss how to tackle the city in general. Then there will be talk of a plan for cruise ships to bypass the historic centre and the mega-project MOSE designed to protect the Venice Lagoon from flooding.
Current flood damage is estimated at hundreds of millions of euros. Once the government declares a state of emergency, EUR 5,000 will be immediately paid to the injured individuals and EUR 20,000 to the injured legal entities.


Goldbach’s Conjecture
问题描述 :
For any even number n greater than or equal to 4, there exists at least one pair of prime numbers p1 and p2 such that
n = p1 + p2
This conjecture has not been proved nor refused yet. No one is sure whether this conjecture actually holds. However, one can find such a pair of prime numbers, if any, for a given even number. The problem here is to write a program that reports the number of all the pairs of prime numbers satisfying the condition in the conjecture for a given even number.
A sequence of even numbers is given as input. There can be many such numbers. Corresponding to each number, the program should output the number of pairs mentioned above. Notice that we are interested in the number of essentially different pairs and therefore you should not count (p1, p2) and (p2, p1) separately as two different pairs.
输入:
An integer is given in each input line. You may assume that each integer is even, and is greater than or equal to 4 and less than 215. The end of the input is indicated by a number 0.
输出:
Each output line should contain an integer number. No other characters should appear in the output.
样例输入:
6 10 12 0
样例输出:
1 2 1
解题代码:
//* @author<EMAIL_ADDRESS>import java.util.Scanner; public class Main { public static boolean isPrime(int n) { int root = (int) Math.sqrt(n); for (int i = 2; i <= root; i++) { if (n % i == 0) return false; } return true; } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n; while ((n = in.nextInt()) != 0) { if(n == 4) { System.out.println(1); continue; } int count = 0; for (int i = 3; i <= n / 2; i+=2) { if (isPrime(i) && isPrime(n - i)) { count ++; } } System.out.println(count); } } }
分析的很专业！
对，算是枚举吧，已修正
很好的方法，学习了
没有对题目进行一番分析，真是美中不足啊
顺利测试通过了，多谢
思路二可以用一个长度为k的队列来实现，入队后判断下队尾元素的next指针是否为空，若为空，则出队指针即为所求。
很有用，收藏了
说的就是无向图啊，有向图的算法也是类似的
妈呀！这个Dijkstra模板好长OwQ！
图像处理那题解题报告在哪儿呢？
我想整理一下leetcode的题解，站长能不能给权限
因为是要把从字符串s的start位到当前位在hash中重置，修改提交后能accept，但是不修改居然也能accept
为什么暴力求解方法循环到sqrt(n) 就可以了呢
这道题目重复了，删掉一个吧


GorillaScript is a compile-to-JavaScript language designed to empower the user while attempting to prevent some common errors.
JavaScript has a lot of warts in the language and while the ECMAScript community is doing a good job with its upcoming revisions, it’s still left with a lot of the old cruft. Also, for those who want to code for older browsers, all the shiny new features that the newer versions of ECMAScript provide are for all intents and purposes unreachable.
==
and !=
perform type coercion behind the scenes and can be the cause of some subtle bugs.
// JavaScript, all the following are true
1 == "1"
0 != ""
3 == "03"
[] == ""
[] == 0
[] == ![]
[] == false
null != false
null == undefined
These could all be fixed by adding an extra equal sign, but GorillaScript makes ==
and !=
strict by default. If one really wants the unstrict equality operators, one can use ~=
and !~=
, but it is not recommended except for comparing against null or undefined, which has the nice postfix operator ?
.
+
operator (and +=
)+
can mean one of two things in JavaScript, addition or string concatenation. There is no way to know at compile-time what the consequences of using +
is unless one is 100% certain what each type is.
x + y
Is addition unless both x
and y
are numbers, booleans, undefined, or null, with any mixed variation. If either is not one of those, at which point it performs string concatenation.
// JavaScript
1 + 2 === 3 // as expected
"hello, " + "world" === "hello, world" // as expected
"hello, " + 123 === "hello, 123" // sure, I can accept this
"1" + 2 === "12"
1 + "2" === "12"
// and for some oddities
false + false === 0
false + true === 1
true + true === 2
null + null === 0
isNaN(undefined + undefined)
[] + [] === ""
{} + {} === "[object Object][object Object]"
true + [] === "true"
new Date() + 1 === "Tue Jan 29 2013 20:25:58 GMT-0800 (PST)1" // or something like it
new Date() - 1 ===<PHONE_NUMBER>072 // or some other number
var foo = {
toString: function () { return 5; }
valueOf: function () { return "foo"; }
};
foo.toString() + 1 === 6
foo + 1 === "foo1"
GorillaScript solves this by splitting the operator into two: +
for addition and &
for string concatenation.
// GorillaScript
1 + 2 == 3
"hello, " & "world" == "hello, world"
"hello, " & 123 == "hello, 123" // concatenation with numbers still works perfectly fine
1 & 2 == "12" // despite both being numbers, & always makes a string.
1 + "2" // TypeError
"1" + 2 // TypeError
"1" + "2" // TypeError
false + false // TypeError
null + null // TypeError
void + void // TypeError
[] + [] // TypeError
{} + {} // TypeError
new Date() + 1 // TypeError
new Date().getTime() + 1 ==<PHONE_NUMBER>072 // or some other number
As can be seen, the operators which don’t fit the proper types exactly fail immediately, allowing one to catch bugs as early as possible rather than allowing them to permeate through one’s programs.
Don’t be worried about losing the bitwise and operator, that is now called bitand
.
All GorillaScript code is wrapped in an immediately-invoked function expression (IIFE) which has the declaration of "use strict"
. This ensures that on the engines that support it, strict semantics will be followed, meaning less bugs in the long run.
All operators check the types of their operands to assure that there will be no improper inputs and that any errors that do occur are caught as early as possible.
==
and !=
do not check the types, since they are already strict by default (in GorillaScript).<
, >
, <=
, >=
are restricted to primitive String
s and Number
s, but never mixing the two.+
only works on primitive Number
s.&
, the new string concatenation operator, works on primitive String
s and Number
s.-
, *
, /
, \
(floor division), %
, %%
(divisible-by), ^
(exponentiation, not bitwise xor), bitand
(instead of &
), bitor
(instead of |
), bitxor
(instead of ^
), bitnot
(instead of ~
), bitlshift
(instead of <<
), bitrshift
(instead of >>
), biturshift
(instead of >>>
), -
(unary negate), +
(unary coerce-to-number), and all their respective assignment operators (-=
, +=
, etc.) all only work on primitive Number
s.No other operators’ types are checked.
If one really wishes to work in an environment where the operands’ types are not checked, one can always prepend the operator with ~
, so there is a ~*
operator which performs multiplication without checking. It is recommended to instead parse input data into conforming types before performing operations on them.
Thankfully, GorillaScript is able to tell which types most values are, so in the general case, there should be little to no runtime type checking occurring.
GorillaScript uses two separate tokens for declaration as compared to assignment. Also, instead of JavaScript’s var
keyword, GorillaScript uses let
. Unless one specifies let mutable
, the local constant cannot be reset to any other value. The object in the value can still be mutated (assuming it is mutable). This can prevent some errors and often helps with the clarity of one’s code.
Also, no undeclared variables can be altered, preventing unexpected global pollution (and typos).
let x = 5
x := 6 // Error
let mutable y = 5
y := 6 // perfectly fine
z := 6 // never declared, this is an error
As you may have noticed, there are two different operators for declaration =
as compared to assignment :=
. This is to clarify the difference. In an ideal program, having as little mutable state as possible is best, so if :=
jumps out, that’s a good thing.
Instead of using braces to dictate code blocks, GorillaScript opts for whitespace indentation as a way to mark blocks. Although this may be jarring at first and one may be skeptical, any good programmer properly indents his or her code to have a consistent whitespace anyway. GorillaScript does not dictate how many spaces or tabs are used, as long as it is consistent within any given block.
if hello
if loudly
"HELLO!"
else
"hi"
else
"Goodbye."
You may have also noticed the lack of semicolons. The parser is able to tell when the end of a statement is without them, so they are unnecessary.
Many of the operators have changed to provide more clarity or to free up the usage of certain symbols.
===
- ==
!==
- !=
==
- ~=
!=
- !~=
!x
- not x
+
- +
for addition, &
for string concatenation, type-checked&
- bitand
, type-checked|
- bitor
, type-checked^
- bitxor
, type-checked~x
- bitnot x
, type-checked<<
- bitlshift
, type-checked>>
- bitrshift
, type-checked>>>
- biturshift
, type-checked--x
- x -= 1
, type-checked++x
- x += 1
, type-checkedx--
- post-dec! x
, not recommended except for advanced casesx++
- post-inc! x
, not recommended except for advanced cases&&
- and
||
- or
, can no longer be used with and
unless one group is in parentheses.x ? y : z
- if x then y else z
key in obj
- obj haskey key
, reversed arguments. Can use not haskey
obj instanceof constructor
- Can also use not instanceof
delete x.y
- Returns the value of x.y
as well as deleting. Does not work on global variables anymore, use delete GLOBAL.x
Kept the same:
<
- type-checked<=
- type-checked>
- type-checked>=
- type-checked-
- type-checked*
- type-checked/
- type-checked%
- type-checked-x
- type-checked+x
- type-checkedx[y]
typeof x
throw x
- Can now be used as an expressionAdded:
typeof! x
- displays the constructor name of the object, typeof! {} == "Object"
, typeof! [] == "Array"
throw? x
- Only throws x
if x
is not null or undefined.x ^ y
- Same as Math.pow(x, y)
x \ y
- Same as Math.floor(x / y)
xor
- For logical completeness with and
and or
x and= y
- Same as if x then x := y
x or= y
- Same as if not x then x := y
x in y
- Does x
exist in array y
. Can use not in
. Highly efficient if y
is a literal array.x ownskey y
- Does x
own the property named y
. Can use not ownskey
x <=> y
- if x == y, 0. if x < y, -1. otherwise, 1.x %% y
- Is x divisible by y
? Same as x % y == 0
.x min y
- Choose the lower number or lexicographically lesser stringx min= y
- If y
is less than x
, set x
to y
.x max y
- Choose the higher number or lexicographically greater stringx max= y
- If y
is greater than x
, set x
to y
.x?
- Is x
null
or undefined
?x ? y
- If x
is null
or undefined
, then y
, otherwise keep the value of x
. y
may not be executed.x ?= y
- If x
is null
or undefined
, then set x
to y
. y
may not be executed.is-array! x
- True if x
is an Array (and not just an Array-like object). Works on arrays from a different context.is-object! x
- True if x
is an Object and not null. Works on objects from a different context.x to y
- Create an array from x
to inclusive y
.x til y
- Create an array from x
until exclusive y
.array by step
- Take every step
th value from the array. If step
is less than 0, go in reverse.x to y by step
- Create an array from x
to inclusive y
, stepping by step
.x til y by step
- Create an array from x
until exclusive y
, stepping by step
.x instanceofsome y
- Iterate over array and check with instanceof
. Highly efficient if y
is a literal array.x is y
- Works like the ECMAScript6 Object.is, which is like GorillaScript’s ==
, but differentiating between 0
and -0
and properly comparing NaN is NaN
. Not recommended to use unless you know you’re working with numbers.x isnt y
- Same as not (x is y)
x << y
- Compose x
and y
, like #(...args) -> x(y(...args))
x >> y
- Compose y
and x
, like #(...args) -> y(x(...args))
x |> f
- Pipe x
into f
, like f(x)
f <| x
- Pipe x
into f
, like f(x)
x <<< y
- Import all properties from y
into x
, like for k, v of y; x[k] := v
x >>> y
- Import all properties from x
into y
, like for k, v of x; y[k] := v
There are two ways to specify functions, one directly using let
, and one as an anonymous function. Also, unlike JavaScript, the last expression is automatically returned (unless tagging the function with !
). Functions can be called optionally without parentheses, as long as it is unambiguous.
let increment(x)
x + 1
assert increment(0) == 1
assert (increment 1) == 2
assert 3 == increment 2
let run(callback)
callback()
assert run(#-> "hello") == "hello"
assert (run #-> "there") == "there"
assert run(#
"you") == "you"
assert run(#
let x = "guys"
"good " & x) == "good guys"
// this syntax also works
let f() -> Math.random()
console.log f()
The outer this
can also be captured be appending @
to the head of the function declaration, creating a “bound” function. This is similar to ECMAScript 5’s Function.prototype.bind
, but more efficient since a hidden _this
variable is used rather than an extra function call.
let func()
let inner()@
this
assert func() == this
Inside double-quoted strings ("like this")
, not single-quoted strings ('like this')
, one can specify string interpolations using the $
symbol, followed by an identifier or a parenthetical expression.
let hello(name)
"Hello, $name"
assert hello("World") == "Hello, World"
assert hello("Universe") == "Hello, Universe"
// or
let greet(names)
"Hello, $(names.join ', ')"
assert greet(["World", "Universe"]) == "Hello, World, Universe"
To specify an optional parameter, one simply need to specify = value
in the function parameter list.
let hello(name = "World")
"Hello, $name"
assert hello() == "Hello, World"
assert hello("Universe") == "Hello, Universe"
If a value is passed in that is null or undefined, it will be automatically turned into the default value.
Instead of using JavaScript’s atrociously broken arguments
special, one can specify a spread parameter by prefixing ...
. Only one can occur in a function parameter list, but it can be at any position.
let hello(...names)
if names.length == 0
"No one is here"
else
"Hello, $(names.join ', ')"
hello() == "No one is here"
hello("World") == "Hello, World"
hello("World", "Universe") == "Hello, World, Universe"
And so that callers don’t feel bad about themselves, you can call with spread as well.
let f(a, b, c) -> [a, b, c]
let items = [1, 2]
f(0, ...f(...items, 3), 4)
Although completely optional to use if you prefer using camelScript
-style identifiers, one can now specify identifiers with dashes, such as my-name
or gorillas-are-awesome
. They are turned into myName
and gorillasAreAwesome
, respectively.
let gorillas-are-awesome = "Yes, they are."
All numbers can have arbitrary underscores in the middle of them, which can be used for thousands separators or bitwise n-bit separators. (1_234_567
or 0x1234_5678_90ab_cdef
)
Decimal numbers can have inline-comments appended to them after an underscore. (1000_ms
)
Octals use the format 0o12345670
instead of 01234567
, to help with clarity.
Binary numbers are available with the format 0b10101010
.
Arbitrary-radix numbers are available by specifying a decimal number between 2 and 36, r
, and the number. (4r01230123
, 36rjdhremn
)
let time = 10_000_ms
let hex = 0x1234_5678
let octal = 0o070
let binary = 0b1010010101
let radix = 36rNFfdH45
let float = 123_456.789_012
Non-decimals do support floating point unlike JavaScript, though that is a lesser-used feature.
Aside from the already-seen string interpolation, there are also triple-quoted strings, which allow for multi-line and are indentation-friendly.
let name = "Jimmy"
let string = """
Hello there.
I have a story to tell you, $name.
I can't think of it right now, though.
"""
The indentation is stripped (but not line 2’s, since that's deliberate), and interpolation is done for $name
, and the first and last newlines are removed. This all occurs at compile-time, so your result code will be as fast as possible.
There are also string like '''this'''
which do not have interpolation, if you wish to use it.
There is also a short syntax for single-word strings that also convert dashed-names
to camelCase
just as normal identifiers do.
assert "Jimmy" == \Jimmy
assert object.some-key == object[\some-key]
assert "someKey" == \some-key
GorillaScript includes all the escape sequences you may be familiar with in JavaScript, such as \0
, \t
, \v
, and many more. You needn’t worry about some non-standard escape codes such as \v
, as GorillaScript compiles to the lowest common denominator.
It also includes the \u
unicode escape sequence which takes 4 hex characters trailing it and \x
which takes 2 hex characters trailing it.
Unlike JavaScript, GorillaScript can properly handle unicode code points greater than 0xFFFF
, by having the \u{}
syntax. Inside the braces, one can put between 1 and 6 hex characters as long as the representation doesn't exceed 0x10FFFF
. This will be split up into two UTF-16 code points if exceeding 0xFFFF
.
let escapes = "\b\f\r\n\t\v\0\1\2\3\4\5\6\7"
let hex = "\xe9"
let unicode = "\u1d25"
let large-unicode = "\u{20bb7}"
Although the standard JavaScript-style syntaxes work, there are a few other ways to specify objects and arrays.
let list = [1, 2, 3]
let other-list = [...list, 4, 5, 6] // now contains [1, 2, 3, 4, 5, 6]
// another way to specify an array
let items =
* "Apples"
* "Bananas"
* "Cherries"
let obj = {
list // same as list: list
sum: 6
f() -> "result" // same as f: #() -> "result"
}
let great-apes =
bonobos:
awesomeness: "pretty cool"
population: 40_000
humans:
awesomeness: "let's not say anything bad about these guys"
population: 7_000_000_000
gorillas:
awesomeness: "clearly the best"
population: 100_000
let special = {
[1 + 2]: "three"
"key$i": "interpolated key"
class: "JavaScript would fail on the 'class' key."
}
To specify the prototype of an object:
let parent = { hello: \there }
let child = { extends parent
value: 1
}
assert child.hello == \there
assert child.value == 1
Map
and Set
are available in the upcoming ECMAScript 6 and in some existing JavaScript engines. There are also shims to provide support in engines that do not support it out-of-the-box.
GorillaScript will automatically provide a shim if used, but it is recommended to use either a native implementation or a more-efficient shim.
Map
is similar to Object
, except its keys are not required to be String
s, but can be any type. Also, access and assignment is done through method calls rather than raw dot-access.
Set
is a collection of unique values, similar to a Map
where all values are true
.
GorillaScript has syntax for declaring both of these as literals, just as one can do with Array
s or Object
s.
let obj = {}
let other = {}
let map = %{
[obj]: 1
[other]: "hello"
}
assert map.get(obj) == 1
assert map.get(other) == "hello"
map.delete other
assert map.has obj
assert not map.has other
map.set other, "there"
assert map.has other
assert map.get(other) == "there"
let set = %[obj, other]
assert set.has(obj)
assert set.has(other)
set.delete(other)
assert not set.has(other)
set.add other
assert set.has(other)
set.add other // does nothing, already in the set.
To correlate with the if
statement, there is also an unless
statement which works as its exact opposite.
if hates-bananas
"You monster."
else unless loves-gorillas
"How could you?"
else if likes-the-gorillaz
"Fire comes out of the monkey's head."
else
"Well, at least you love gorillas and don't hate bananas."
GorillaScript provides many different looping constructs, all fitted for their own purposes.
Normal while loop, same as JavaScript:
let mutable i = 0
while i < 10
console.log i
i += 1
Opposite of a while loop, until
:
let mutable i = 0
until i >= 10
console.log i
i += 1
Better version of the above, acts like JavaScript’s for(;;)
let mutable i = 0
while i < 10, i += 1
console.log i
Even better version:
for i in 0 til 10
console.log i
Or if you want to go in reverse,
for i in 9 to 0 by -1
console.log i
Or by twos:
for i in 0 til 10 by 2
console.log i
You don’t have to use literal numbers, they can be any expression in GorillaScript. You can also use to
, til
, and by
to make arrays outside of loops.
The difference between til
and to
is that til
goes up until it hits the end, but to
includes the end.
To iterate over an array,
for food in ["Apples", "Bananas", "Cherries"]
console.log food
If you want its index,
for food, index in ["Apples", "Bananas", "Cherries"]
console.log "$index: $food"
You can also get the total length of the array, if you need it:
for value, index, length in some-array
f()
To iterate an array in reverse (slightly more efficient):
for value, index in some-array by -1
// index goes from some-array.length - 1 down to 0.
console.log value
To iterate only a part of the array:
for value in some-array[2 to 5]
console.log value
It works similarly to some-array.slice(2, 6). You can slice outside of loops as well.
To iterate over objects, you can use of
instead of in
:
for key, value of some-object
console.log key, value
GorillaScript automatically runs an Object.prototype.hasOwnProperty check on the key. To avoid this, use:
for key, value ofall some-object
console.log key, value
Any loop can be an expression simply by returning it or assigning it to a variable. This will create an array.
let squares = for value in 0 to 10
value ^ 2
// squares now contains [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Single-line loops can be specified as so:
let squares = for value in 0 to 10; value ^ 2
There are also reducing loops which work by placing one of the reducers (first
, every
, some
, filter
, reduce
) on the for
or while
loop.
let all-good = for every item in array; item.is-good()
let has-bad = for some item in array; item.is-bad()
let best-value = for first item in array
if item.is-best()
item.value
let only-good = for filter item in array; item.is-good()
let sum = for reduce value in [0, 1, 2, 3, 4], current = 0
current + value
These work on any for
or while
loop.
A common bug in JavaScript is when one creates a function inside a loop that refers to the current index or value or some other variable that changes each loop iteration. GorillaScript solves this problem by wrapping any for loop that creates a function in another function, so the following works by seemingly lexically-scoping the inside of the for loop rather than abiding by JavaScript’s normal function scoping.
let funcs = []
for i in 0 til 10
funcs.push #-> i
funcs[0]() == 0
funcs[5]() == 5
With no extra work on the developer’s part.
As mentioned briefly earlier, one can use the to
, til
, and by
syntaxes to slice on arrays.
let array = [\a, \b, \c, \d, \e]
assert-arr array[1 to 3], [\a, \b, \c]
assert-arr array[1 to 5 by 2], [\a, \c, \e]
assert-arr array[5 to 1 by -2], [\e, \c, \a]
assert-arr array by -1, [\e, \d, \c, \b, \a]
assert-arr array[0 to -1], [\a, \b, \c, \d, \e]
assert-arr array[0 to Infinity], [\a, \b, \c, \d, \e]
The negative values work just as they do in .slice
, unlike normal accessing
GorillaScript can’t wrap every single access in a check to see if the child is a negative value (as Python or some other languages do), due to efficiency, but it does provide a nice syntax to make it easier.
let array = [\a, \b, \c, \d, \e]
assert array[* - 1] == \e
assert array[* - 2] == \d
assert array[* \ 2] == \c // halfway point in the array
When a standalone *
is encountered in an index, it is converted to the current array’s .length
.
Unlike JavaScript, for
loops, while
loops, try
blocks, and if
constructs can be used as expressions.
let array = for i in 0 to 10; i
let trial = try
throw Error()
catch e
"Caught something"
assert trial == "Caught something"
let check = if youre-amazing
"It's true"
else
"Not amazing."
If one wishes to check a value against null or undefined, the existential operator (?
) can be used.
let exists = value?
It can also be used for access soaking
let inner = value?.which.might?.not.exist
Turns into
let inner = if value?
let _ref = value.which.might
if _ref?
_ref.not.exist
It can also be used for function checking
let result = f?()
Turns into
let result = if typeof f == \function
f()
in
operatorTo correlate with array iteration, in
checks if a value is in an array, in a similar way to array.indexOf(value) != -1
would.
assert \hello in [\hi, \there, \hello]
To check if an object contains a key, see the haskey
operator.
haskey
and ownskey
Instead of using JavaScript’s in
, haskey
is used to verify a key’s existence on an object. Also, ownskey
is also available to check if a key exists on an object without prototype-checking.
let parent = { alpha: \bravo }
let child = { extends parent, charlie: \delta }
assert parent haskey \alpha
assert parent ownskey \alpha
assert parent not haskey \charlie
assert parent not ownskey \charlie
assert child haskey \alpha
assert child not ownskey \alpha
assert child haskey \charlie
assert child ownskey \charlie
Sometimes you may have an object where you want to access its key but only in the case of the object owning the key as a property.
assert if parent ownskey key
parent[key]
// functionally equivalent to
assert parent![key]
Or, for a known key:
assert if parent ownskey \key
parent.key
assert parent!.key
In JavaScript, if you wish to specify the this
argument passed to a function, one must use either .call
or .apply
. GorillaScript provides the @
syntax:
let f() -> this
let obj = {}
assert obj == f@ obj
assert obj == f@(obj)
Array.prototype.slice@ arguments, 1
It transparently converts to .call
or .apply
(whichever is more appropriate), using the first argument as its this
.
ECMAScript 5 supplies Function.prototype.bind
as a way to bind functions to a specific this (and specify arguments). To do a similar binding in GorillaScript, one need only use the familiar @
syntax with access.
let obj = {
f: # -> this
}
let bound =<EMAIL_ADDRESS>assert bound() == obj
let unbound = obj.f
assert unbound() == window
GorillaScript provides a way to make classical-style classes. JavaScript does not have classes normally, so GorillaScript’s creation is slightly hackish, but works for the general case.
class Animal
def constructor(@name) ->
def eat() -> "$(@name) eats"
class GreatApe extends Animal
// no constructor, Animal's is automatically called
def eat(food="fruit") -> super.eat() & " a " & food
class Gorilla extends GreatApe
def constructor(@name, @favorite-food)
// important to call the super constructor.
super(@name)
def eat() -> super.eat(@favorite-food)
class Chimp extends GreatApe
def eat() -> super.eat("banana")
let bobo = Chimp("Bobo") // new is not required on GorillaScript-made classes
assert bobo.eat() == "Bobo eats a banana"
let toko = Gorilla("Toko", "cherry")
assert toko.eat() == "Toko eats a cherry"
// set a method on the Gorilla constructor
Gorilla::barrel := # -> @name & " throws a barrel!"
assert toko.barrel() == "Toko throws a barrel!"
Classes can extend
other classes and call into their superclass with super
. The constructor functions automatically check the this
argument and if it is not the current class’s type (such as when called without new
), it will create a new one on-the-fly.
GorillaScript, like ECMAScript 6, provides a destructuring declaration.
let [x, y] = [1, 2]
assert x == 1
assert y == 2
let {a, b: c} = {a: 3, b: 4}
assert a == 3
assert c == 4
These can be nested like so:
let [a, {b, c: [d]}] = get-data()
And the spread operator (...
) can be used once per array destructure:
let [value, ...rest] = array
Like JavaScript, GorillaScript provides switch
. The only major exception is that JavaScript is fallthrough-by-default, and GorillaScript is break-by-default. GorillaScript can also specify multiple values to check at once instead of having multiple cases. switch
can also be used as an expression.
switch value
case 0, 1, 2
"small"
case 3, 4, 5
fallthrough // in the last position of the case, causes the case to fall through to the next case.
case 6, 7, 8
"large"
default
"unknown"
Unlike JavaScript, GorillaScript provides a topicless switch
, which works by checking if each case is truthy rather than comparing against a value. fallthrough
works the same way as a normal switch statement. This does not generate a JavaScript switch
statement, as it is extremely inefficient to use switch
in JavaScript without constant case
checks.
switch
case is-good()
"good"
case is-bad()
"bad"
default
"neutral"
Try-catch also works similarly to JavaScript, except that catches can have type-checks and the notable exception of the else
statement, for when no error was caught, but occurs before the finally
statement.
try
something-dangerous()
catch e as SpecificError
handle-error(e)
catch e
uh-oh()
else
whew()
finally
cleanup()
At least one of catch
, else
, or finally
must be used, but so can all three.
Unlike JavaScript, Regular Expressions borrow the string syntax simply prefixed with r
and postfixed with any RegExp flags deemed necessary. Also, if triple-quoted strings (e.g. r"""reg"""g
) are used, all spaces are ignored as well as any # hash comments
r"l".test "apple"
let regex = r"""
This is a large regex, $name
And all the space is ignored # and this is ignored, too!
"""gim
If one doesn’t wish to use simple string concatenation with string interpolation, %
can be prefixed to any double-quoted string to return an array instead which can then be interpolated in a custom manner. All even-numbered strings are guaranteed to be source literals and all odd-numbered values (might not be strings) are interpolated input.
The following is an example of automatic HTML escaping, but the same concept could be applied to SQL strings or practically any string with unsafe input.
class SafeHTML
def constructor(@text as String) ->
def to-string() -> @text
let to-HTML = do
let escapes = {
"&": "&"
"<": "<"
">": ">"
'"': """
"'": "'"
}
let replacer(x) -> escapes[x]
let regex = r"[&<>""']"g
let escape(text) -> text.replace(regex, replacer)
#(arr)
(for x, i in arr
if i %% 2 or x instanceof SafeHTML
x
else
escape String(x)).join ""
assert "<h1>normal</h1>" == to-HTML %"<h1>normal</h1>"
let evil-name = "<\"bob\" the 'great' & powerful>"
assert "<"bob" the 'great' & powerful>" == to-HTML %"$evil-name"
assert "<span><"bob" the 'great' & powerful></span>" == to-HTML %"<span>$evil-name</span>"
assert "<span><\"bob\" the 'great' & powerful></span>" == to-HTML %"<span>$(SafeHTML evil-name)</span>"
Iterators are an ECMAScript 6 feature that have been in Mozilla’s JavaScript since 1.7. GorillaScript can both produce and consume such iterators.
for value, index from some-iterable
console.log value
Turns into the following code:
let _iter = some-iterable.iterator()
try
let mutable index = -1
while true
index += 1
let value = try
_iter.next()
catch e
if e == StopIteration
break
else
throw e
console.log value
finally
_iter?.close?()
Which means that any object that implements the iterator
method acts as an iterable. That return value merely needs to implement the next
method, and optionally a close
method.
If Array.prototype
were to implement iterator
, which the ECMAScript 6 draft is recommending, one could iterate over Array
s, Set
s, Map
s, but one can iterate over any custom type now or by simply adding an Array.prototype.iterator
method.
Production of iterators is easy as well in GorillaScript. You need merely append the *
and use the yield
statement.
let fib()*
let mutable a = 0
let mutable b = 1
while true
yield b
let tmp = a
a := b
b += tmp
Produces an iterable which returns the infinite sequence of fibonacci numbers. The resultant code looks something along the lines of:
let fib()
let mutable a = 0
let mutable b = 1
let mutable _state = 0
{
iterator: #-> this
next: #
while true
switch _state
case 0
_state := 1
return b
case 1
let tmp = a
a := b
b += tmp
_state := 0
}
The state machine is made for you and any GorillaScript construct can be used inside a generator function (except for return
).
One could then easily then use the fib iterator:
for value from fib()
console.log value
if value > 4000000
break
GorillaScript provides a whole slew of asynchronous-capable syntax to make dealing with “callback hell” just a little easier. Since JavaScript fundamentals and frameworks (node.js, for example) tend to be very async-friendly, this is especially helpful.
async err, text <- fs.read-file "somefile.txt", "utf8"
throw? err
console.log text
No indentation necessary, every line following the async call will be part of the implicitly-constructed callback. The resultant code looks like:
fs.read-file "somefile.txt", "utf8", #(err, text)@
throw? err
console.log text
Although that may not seem too useful with only one block of indentation, when dealing with complex database access or multiple sources of input, it is very easy to become overwhelmed.
In the case where you don’t want to throw the error, but instead need to pass it to a callback (which takes the error as the first argument), you have one of two options:
let run(callback)
async err, text <- fs.read-file "somefile.txt", "utf8"
if err?
return callback err
callback null, do-something(text)
Or you can use
let run(callback)
async! callback, text <- fs.read-file "somefile.txt", "utf8"
callback null, do-something(text)
Which is functionally equivalent.
Often, one may use a library to manage asynchronous handling of loops and iteration over arrays, but that is all built right into GorillaScript. Every loop construct you’ve seen works seamlessly by prepending async
and specifying the next
callback.
The next
callback expects 0 to 2 arguments, if it receives a non-null
-or-undefined
value as its first argument, it will halt the loop immediately, as an error or other break has occurred. If it receives a second argument, it will append that value to an array, which may be optionally requested by the developer.
asyncfor
loops can specify their level of parallelism manually (defaulting to 1
, which runs serially). If parallelism is set to 0
, it runs completely parallel.
// read two files at a time
asyncfor(2) err, array <- next, filename in ["a.txt", "b.txt", "c.txt", "d.txt"]
async err, text <- fs.read-file filename, "utf8"
if err?
// if an error occurs, it propagates up and no more files will be read, and post-async execution
// will occur immediately.
return next err
next null, { filename, text }
throw? err
console.log array // array will now be filled with objects like { filename: "a.txt", text: "lots of text here" }
Which turns into a device which looks something like:
let _array = ["a.txt", "b.txt", "c.txt", "d.txt"]
__async-result 2, array.length,
#(i, next)@
let filename = array[i]
fs.read-file filename, "utf8", #(err, text)@
if err?
return next err
next null, { filename, text }
#(err, array)@
throw? err
console.log array
There is also asyncwhile
and asyncuntil
, which work similarly to their normal constructs but require the next
argument to inform the code that its execution has completed one way or another.
If you wish to use conditionals which may or may not have asynchronous code inside their bodies, asyncif
or asyncunless
is necessary.
asyncif text <- next, some-boolean()
async err, text <- fs.read-file filename, "utf8"
throw? err
next(text)
// else is optional, will automatically call next() if not provided
console.log text
Which turns into something like:
let next(text)
console.log text
if some-boolean()
fs.read-file filename, "utf8", #(err, text)@
throw? err
next(text)
else
next()
returning
Occasionally, one needs to return a value such as false
in an event handler, while using an asynchronous command. This is where the returning
statement comes in. It works just like return
, only it runs at the end of its block rather than where it is placed.
register-event #(filename)
returning false
async err, text <- fs.read-file filename, "utf8"
throw? err
console.log text
Which turns into:
register-event #(filename)
fs.read-file filename, "utf8", #(err, text)
throw? err
console.log
return false
On parameters, one can put types in the format param as Type
. These will be checked at runtime and the type inference engine will be aware of them.
The types String
, Number
, Boolean
, and Function
will check against typeof
, not with instanceof
.
null
, void
, and undefined
(alias for void
) are also seen as valid types.
Arrays can be made using the syntax of []
for an array of any type or [Type]
for a specific array. The contents will be checked at runtime.
Objects can be made using the standard object syntax with all values being types, e.g. {x: Number, y: String}
Functions with specific parameters or return value can be defined with ->
for any parameter, any return. -> Type
for a specific return value, Type -> Type
for a single-argument with a specific return value, or (Type, Type) -> Type
for two arguments with a specific return value.
Type unions can be made with |
, e.g. Number|String
. Order is irrelevant.
One can also place a return type on functions, which is not checked at runtime, but is used by the type inference engine.
Some examples:
let increment(x as Number) -> x + 1
let greet(x as String|Number) -> "Hello, $x"
let run(x as -> Number) -> x()
let get-number() as Number -> num
let join(x as [String]) -> x.join ", "
let use-object(o as {x: Number, y: Number}) -> o.x + o.y
Types can also be placed on let statements, to help with the type inference engine.
let x as Number = f()
In functional programming, it is often handy to use one of the built-in operators as a function, and GorillaScript provides this capability.
let add = (+) // same as #(x, y) -> x + y
assert add(5, 6) == 11
let square = (^ 2) // same as #(x) -> x ^ 2
assert square(10) == 100
let double = (2 *) // same as #(x) -> 2 * x
assert double(5) == 10
let invert = (not) // same as #(x) -> not x
assert invert(true) == false
assert invert(false) == true
assert 10 == [1, 2, 3, 4].reduce (+)
Any binary operator can be used this way, and any unary operator can be used as long as it does not share the same token as a binary operator.
One can also use the same syntax for accesses and method calls
let get-length = (.length) // same as #(x) -> x.length
assert get-length("hello") == 5
let to-hex = (.to-string(16)) // same as #(x) -> x.to-string(16)
assert to-hex(255) == "ff"
Getter and setter support is up to the engine to support, and is therefore not recommended to be used in the general case. Even Internet Explorer 8 only provides support if the object is a DOM Element, so I cannot recommend using them on a broad scale unless you control the JavaScript engine (such as in node.js).
There are two ways to define getters and setters:
let obj =
_x: 0
get x: # -> @_x
set x: #(value)! -> @_x := value
_y: 0
property y:
get: #-> @_y
set: #(value)! -> @_y := value
configurable: true
enumerable: true
When using the get
and set
pair, they must be defined next to each other (order is irrelevant). One can also supply only get
or only set
.
When using the property
syntax, the value is the same as one calling Object.defineProperty
, in fact, that is all that is happening behind the scenes.
If Object.defineProperty
is not available, then it will try to sanely fallback, but it might not be successful. If specifying value
instead of get
/set
, it will always work, but the configurable
/enumerable
/writable
attributes are not guaranteed.
Note: this might throw an Exception
if Object.defineProperty
is not defined
break
/continue
JavaScript provides a way to add a label to a block and then be able to break
or continue
(if it is a loop) on that block.
Although it is not recommended practice, as one is probably better served by rethinking the algorithm, GorillaScript does provide the capability.
let mutable sum = 0
label! outer for i in 0 to 10
for j in 0 to 10
if i == j
continue outer
sum += i
As you can see, the outer loop has the label outer
on it and the continue
also references that same label, meaning it will continue on the outer loop rather than the inner.
GLOBAL
identifierSince JavaScript can be run outside the browser now, one cannot rely on window
always being the global object, so GorillaScript provides the GLOBAL
identifier for just this case, which will be window
or global
or the outermost this
, whichever one works best. It is UPPER-CASE and therefore loud for a reason: try to avoid globals when possible.
assert Math == GLOBAL.Math
Currying is a technique of transforming a function which takes multiple arguments in such a way that it can be called as a chain of functions. GorillaScript provides a nice way to automatically curry functions.
let add(a, b, c)^
a + b + c
assert add(1, 2, 3) == 6 // same as before
let add-one = add 1
assert add-one(2, 3) == 6
let add-two = add 2
assert add-two(1, 3) == 6
let add-one-and-two = add-one 2 // or add 1, 2
assert add-one-and-two(3) == 6
Simply by putting the caret (^
) after the function parameters, functions are automatically curried. Curried functions work extremely well in functional-style programming and are extremely handy when coupled with the compose operators (<<
and >>
)
let sort-by(key, array)^
array.sort #(a, b) -> a[key] <=> b[key]
let sort-by-id = sort-by \id
let sort-by-name = sort-by \name
let items =
* id: 0
name: "Dog"
* id: 1
name: "Car"
* id: 2
name: "Robot"
* id: 3
name: "Guitar"
let items-by-name = sort-by-name items
let items-by-id = sort-by-id items
It is not recommended to use currying with default arguments (e.g. #(x = 0)^
) or spread arguments (e.g. #(...args)
), since the curry helper checks a function's .length
to determine how many arguments before calling the actual function, and it may be non-obvious.
GorillaScript supports reified generic classes and functions, which are similar to .NET's generics or C++'s templates.
If a function is called with generic arguments, it is converted as so:
func<String>("hello")
// turns into
func.generic(String)("hello")
How the function handles the .generic
call can vary, but GorillaScript's classes handle it elegantly:
class MyClass<T>
def constructor(@value as T) ->
def get-value() as T
@value
let wrapped-string = MyClass<String>("hello")
let wrapped-number = MyClass<Number>(1234)
let wrapped-any = MyClass({})
In the previous case, MyClass<String>
, MyClass<Number>
, and MyClass
(same as MyClass<null>
) all refer to three independent classes which have different semantics.
You may be wondering about MyClass<null>
, but it simply refers to absolutely any type being accepted, whether it's a String
, Object
, void
, or some custom object.
Type-checking works as expected and T
(or whatever type you call it) is available at runtime to refer to the bound generic type.
Here is an example of a simple function (rather than a class) with generic arguments:
let func<T>(value as T) -> value
assert func<String>("hello") == "hello"
assert func<Number>(1234) == 1234
assert func(true) == true // no type specified, so any type is allowed
assert func(null) == null
It is recommended that you name your generic argument T
or have it start with the letter T
, as in TKey
or TResult
.
GNOME now has JavaScript bindings with Gjs and GorillaScript supports this to the best of its ability.
As long as you have gjs
installed locally, there are three ways to run Gjs with GorillaScript:
REPL: If you run gorilla --gjs
or gjs-gorilla
, a REPL opens that pipes its JavaScript code to gjs
Running a .gs
file: If you run gorilla --gjs myfile.gs
or gjs-gorilla myfile.gs
, it will compile the code of myfile.gs
and pipe its results to gjs
all at once.
Compile and run with gjs
. You can compile any .gs
file as per usual with gorilla -c
and run the result .js
file with gjs
. You'll want to do this before distributing any code anyway.
Aside from being written in GorillaScript rather than JavaScript, it will then function as any other Gjs script
Here is the standard Hello World Gjs code converted to GorillaScript:
#!/usr/bin/env gjs-gorilla
let {Gtk, GLib} = imports.gi
// Initialize the gtk
Gtk.init null, 0
let mwindow = new Gtk.Window type: Gtk.WindowType.TOPLEVEL
let label = new Gtk.Label label: "Hello World"
// Set the window title
mwindow.title := "Hello World!"
mwindow.connect "destroy", #-> Gtk.main_quit()
// Add the label
mwindow.add label
// Show the widgets
label.show()
mwindow.show()
Gtk.main()


CV
Curriculum Vitae (CV) is just a fancy way to say resume in the context of higher education. It is prepared for job, school, and grant applications (or really anytime someone needs to have a summarized version of your qualifications). The CV conveys your personal and professional details. There is no best way to construct a CV (though many fields have semi-standard constructions), but we’ll outline some information to make the document clean, clear and the most helpful to you.
| Category | Resume | CV |
|---|---|---|
| Length | Short | As long as it needs to be |
| Content | All-inclusive summary of skills, experiences and education | Area-specific listing of education and academic background |
| Purpose | Get employment | Detail qualifications |
Advice
Before getting into other advice, I think of the "Cs"- Clear, Concise (but complete), consistent, and current - for your CV
Below you'll find a number of difference resources with advice. If you find conflicting advice across these resources, remember that there is no “right” way, just make sure to follow the “Cs” above and remember that the CV will just be one part of a package of materials any time that it is requested.
How to Write a Curriculum Vitae
Illinois Graduate College Career Development
Converting your resume to a CV
Medical College of Wisconsin CV Samples
Example
You can find an example CV here (.docx download). Remember that there is no agreed upon format to my knowledge. So use this and edit it to your liking. Its best to start with something clean and neat like this and then as you fill out the CV more, to add some more formatting.
References
Kelsky, K. (January 12, 2012). Dr. Karen’s rules of the academic CV. Retrieved from http://theprofessorisin.com/2012/01/12/dr-karens-rules-of-the-academic-cv/
Pomona College. How to Write a Curriculum Vitae. Retrieved from https://www.pomona.edu/administration/career-development/how-to/write-curriculum-vitae
Illinois Graduate College Career Development. Curriculum Vitae Tips and Samples Retrieved from http://www.grad.illinois.edu/sites/default/files/pdfs/cvsamples.pdf
The Ohio State College of Medicine. The CV. Retrieved from http://medicine.osu.edu/students/life/career_advising/pages/cv.aspx
Boston College Law Office of Career Services. (June, 2008). Converting your resume to a CV. Retrieved from https://www.bc.edu/content/dam/files/schools/law/pdf/CareerServicesDocuments/Converting%20a%20resume%20to%20a%20CV%206_08.pdf
Medical College of Wisconsin. CV Samples. Retrieved from http://www.mcw.edu/Medical-School/Current-Students/Academic-Support-Services/CV-Samples.htm


Ocean [as52], ocean, in The Inner Sea
Last updated Turn #48
Ocean [as52], ocean, in The Inner Sea
------------------------------------------------------------------------
20: Travelling Wave [hp7g], ship, 2 hulls, 4 rowing ports, 4% damaged,
20: arrived from Ocean [as53], owner:
20: Stewart [k0u], Pen, with 18 sailors
20: Jonathan [h9k], Pen
21: Travelling Wave [hp7g], ship, 2 hulls, 4 rowing ports, 4% damaged,
21: departed for Ocean [as51].
Routes leaving Ocean:
North, to Ocean [ar52], 6 days
East, to Ocean [as53], 6 days
South, to Ocean [at52], 6 days
West, to Ocean [as51], 6 days


Welcome to JCC, PyLucene's code generator
What is JCC ?
JCC is a C++ code generator that produces a C++ object interface wrapping a Java library via Java's Native Interface (JNI). JCC also generates C++ wrappers that conform to Python's C type system making the instances of Java classes directly available to a Python interpreter.
When generating Python wrappers, JCC produces a complete Python extension module via the distutils or setuptools packages.
See here for more information and documentation about JCC.
Requirements
JCC is supported on Mac OS X, Linux, Solaris and Windows.
JCC requires Python version 2.x (x >= 3.5) and Java version 1.x (x >= 4). Building JCC requires a C++ compiler. Use of setuptools is recommended.
See the installation instructions for more information about building JCC from sources.
Source Code
The source code to JCC is part of PyLucene's and can be obtained with a subversion client from here.
Mailing List
If you'd like to contribute to JCC or are having issues or questions with JCC, please subscribe to the PyLucene developer mailing list.


Try out our Premium Member services: Virtual Legal Assistant, Query Alert Service and an ad-free experience. Free for one month and pay only if you like it.
1 IN THE HIGH COURT OF KARNATAKA AT BANGALORE DATED THIS THE 23rd DAY OF SEPTEMBER 2014 BEFORE THE HON'BLE MR. JUSTICE DILIP B BHOSALE W.P.NOS.25815-25816/2014 (LB-BMP) BETWEEN 1.  MAYOOR KURVA S/O LATE K L KURVA AGED ABOUT 40 YEARS RESIDING AT 14 B, S J R EASTWOOD HARLUR ROAD, OFF SARJAPUR ROAD BANGALORE-560102 ... PETITIONERS (BY SRI ADITYA NARAYAN, ADV.,) AND 1. THE BRUHAT BANGALORE MAHANAGARA PALIKE HUDSON CIRCLE, BANGALORE-560001 REPRESENTED BY ITS COMMISSIONER 2. THE DEPUTY HEALTH OFFICERQQ B T M RANGE BRUHAT BENGALURU MAHANAGARA PALIKE BTM RANGE OFFICE, BBMP BUILDING 16TH MAIN ROAD OPPOSITE CHAMUNDESHWARI KALYANA MANTAPA BTM 2ND STAGE, BANGALORE-560076 ... RESPONDENTS (BY SRI B V MURALIDHAR, ADV.,) 2 THESE W.Ps. FILED UNDER ARTICLES 226 & 227 OF THE CONSTITUTION OF INDIA PRAYING TO QUASH THE IMPUGNED CLOSURE ORDER DT.2.6.2014, VIDE ANNX-A ISSUED BY R-2 AND ETC., THESE W.Ps. COMING ON FOR PRELIMINARY HEARING IN 'B' GROUP, THIS DAY, THE COURT MADE THE FOLLOWING: PC: By consent, heard learned counsel for the parties for admission of the writ petitions. I have perused the amendment application and the proposed amendment. 2. In the present writ petitions, the petitioners have impugned the order dated 02.06.2014 issued by the 2nd respondent-The Deputy Health Officer whereby he has directed the petitioners to close their industry. Petitioners run a printing press at Venkata Reddy Layout, which is predominantly a residential area. They were running the press after obtaining trade licence under the provisions of the Karnataka Municipal Corporation Act, 1976. The trade licence expired on 31.03.2013. Petitioners, therefore, applied for its renewal and the renewal application, according to the petitioners, was kept pending till the impugned order dated 02.06.2014 was issued. 3 3. It is not in dispute that the 2nd respondent took action against the petitioners in view of the show cause notice dated 11.02.2014, issued by the Karnataka State Pollution Control Board (for short "the Board"). It would be relevant to reproduce the text of the show cause notice which read thus: "With reference to above subject, this office has received the complaint against the above industry engaged in the business of digital printing vide ref(1) regarding Smell nuisance and dust particles while cutting sun boards used for hoardings. In response to the complaint, the DEO of this office has inspected the unit on 6.1.2014 vide ref(2) and submitted a report. As per the report, you have established and operating the industry in the name & style of M/s. Welpac Products and Systems Pvt Ltd, No.31, Venkata Reddy Layout, 80 Feet Road, Cross, 6th Block, 3rd Cross, Koramangala, Bangalore-560095 and engaged in Digital printing activity without obtaining consent for establishment (CFE) and consent for operation (CFO) from the KSPCB under the Water (Prevention and Control of Pollution) Act, 1974 & Air (Prevention and Control of Pollution) Act, 1981. During inspection the following observations were made: • The industry is operating and engaged in the Digital printing activity (Printing on Flex/Vinil) and due to which there is a smell nuisance to the surrounding residence. • The industry is established in a residential area even though no industry is allowed to establish/operate in the residential area. • The industry is established in a building having Ground floor, First floor and Second floor. There are Two Large Digital Printing machines which are 4 installed in the ground floor and Two Small Digital Printing machines in the First floor and no activity in the Second floor. • The industry has installed 62.5 KVA DG set with acoustic enclosures. • During inspection it was informed to the Proprietor Sri.Mayoor - to shift the industrial, activity to the industrial area to prevent Health hazardous to the surrounding residents. In view of the above, you are hereby called upon show-cause within 7 days time as to why this office shall not recommend the Board to initiate suitable action as per the relevant provisions of the Water & Air Acts. The receipt of this 'Show Cause Notice' may be acknowledged." Copy of the show cause notice was forwarded to 2nd respondent for information and suitable action, including to withdraw the trade licence in view of the complaints from residents in Venkata Reddy Layout. The petitioners replied to the show cause notice vide their letters dated 28.02.2014 and 06.03.2014 (Annexure-K and L). This Court is informed that the show cause notice is yet not decided by the Board. Learned counsel for the petitioner also informs the Court that the petitioners have also applied for "No Objection" to the Board for running the printing press vide their application dated 23.05.2014 and the same is also pending consideration. In this view of the matter, I do not find any reason to interfere with the 5 impugned order dated 02.06.2014. It is not in dispute that the Board has powers to issue a show cause notice, as issued in the present cases, and even to pass further orders including the order of closure. Similarly, it is also not in dispute that "No Objection" of the Board for running printing press is necessary. Unfortunately, the petitioners have not added the Board as respondent in the petitions. Be that as it may, I do not find any reason to interfere with the order impugned in the present writ petitions and I am satisfied that the following order shall meet the ends of justice: ORDER
i. The Board is requested to decide the show cause notice on merits in accordance with law as expeditiously as possible and preferably within a period of eight weeks from the date of receipt of this order.
ii. The Board is further requested to consider and decide the petitioners' application for seeking No Objection.
6iii. If the orders passed by the Board on the show cause notice as well as on the application filed by the petitioners for seeking no objection are not adverse to the petitioners, it is open to them to approach the BBMP for issue of trade licence or for renewal of earlier trade licence issued to them.
iv. It is needless to mention that if the orders passed by the Board are adverse to the petitioners, it is always open to them to take appropriate remedy against such orders.
v. It is made clear that this Court has not examined merits of the show cause notice and the petitioners' application for seeking No Objection.
With these observations, the writ petitions are disposed of.
Sd/-
JUDGE TL


| PyGeodesy | 20.9.5 | class Cartesian in module | ||||
|---|---|---|---|---|---|---|
| pygeodesy.ellipsoidal- | pygeodesy.spherical- | |||||
| attribute | type | -Karney | -Nvector | -Vincenty | -Nvector | -Trigonometry |
| angleTo | method | D | D | D | D | D |
| attrs | method | F | F | F | F | F |
| classname | property* | F | F | F | F | F |
| classnaming | property | F | F | F | F | F |
| classof | method | F | F | F | F | F |
| cmp | method | D | D | D | D | D |
| convertDatum | method | C | C | C | C | C |
| convertRefFrame | method | B | B | B | - | - |
| copy | method | F | F | F | F | F |
| cross | method | D | D | D | D | D |
| crosserrors | property | D | D | D | D | D |
| datum | property | C | C | C | C | C |
| dividedBy | method | D | D | D | D | D |
| dot | method | D | D | D | D | D |
| Ecef | property* | C | C | C | C | C |
| equals** | method | D | D | D | D | D |
| height | property* | C | C | C | C | C |
| intersections2 | method | - | - | - | B | B |
| isEllipsoidal | property* | C | C | C | C | C |
| isequalTo | method | D | D | D | D | D |
| isSpherical | property* | C | C | C | C | C |
| latlon | property* | C | C | C | C | C |
| latlonheight | property* | C | C | C | C | C |
| latlonheightdatum | property* | C | C | C | C | C |
| length | property* | D | D | D | D | D |
| minus | method | D | D | D | D | D |
| name | property | F | F | F | F | F |
| named | property* | F | F | F | F | F |
| named2 | property* | F | F | F | F | F |
| negate | method | D | D | D | D | D |
| others | method | D | D | D | D | D |
| parse | method | D | D | D | D | D |
| philam | property* | C | C | C | C | C |
| philamheight | property* | C | C | C | C | C |
| philamheightdatum | property* | C | C | C | C | C |
| plus | method | D | D | D | D | D |
| rotate | method | D | D | D | D | D |
| rotateAround** | method | D | D | D | D | D |
| sum | method | D | D | D | D | D |
| times | method | D | D | D | D | D |
| to2ab** | method | D | D | D | D | D |
| to2ll** | method | D | D | D | D | D |
| to3llh** | method | C | C | C | C | C |
| to3xyz** | method | D | D | D | D | D |
| toEcef | method | C | C | C | C | C |
| toLatLon | method | A | A | A | A | A |
| toNvector | method | C | A | C | A | C |
| toRepr | method | E | E | E | E | E |
| toStr | method | C | C | C | C | C |
| toStr2 | method | F | F | F | F | F |
| toVector | method | C | C | C | C | C |
| unit | method | D | D | D | D | D |
| x | property* | D | D | D | D | D |
| xyz | property* | D | D | D | D | D |
| y | property* | D | D | D | D | D |
| z | property* | D | D | D | D | D |
| **) DEPRECATED | *) immutable | A: class attribute | B, C, ...: attribute of a super class |


|
LiteCore
Couchbase Lite cross-platform core implementation
|
Data Structures | |
| struct | C4BlobKey |
| A raw SHA-1 digest used as the unique identifier of a blob. More... | |
Typedefs | |
| typedef struct c4BlobStore | C4BlobStore |
| Opaque handle for an object that manages storage of blobs. More... | |
Blob Keys | |
| bool | c4blob_keyFromString (C4String str, C4BlobKey *) |
| Decodes a string of the form "sha1-"+base64 into a raw key. More... | |
| C4StringResult | c4blob_keyToString (C4BlobKey) |
| Encodes a blob key to a string of the form "sha1-"+base64. More... | |
Blob Store API | |
| C4BlobStore * | c4db_getBlobStore (C4Database *db, C4Error *outError) |
| Returns the BlobStore associated with a bundled database. More... | |
| C4BlobStore * | c4blob_openStore (C4String dirPath, C4DatabaseFlags flags, const C4EncryptionKey *encryptionKey, C4Error *outError) |
| Opens a BlobStore in a directory. More... | |
| void | c4blob_freeStore (C4BlobStore *) |
| Closes/frees a BlobStore. More... | |
| bool | c4blob_deleteStore (C4BlobStore *, C4Error *) |
| Deletes the BlobStore's blobs and directory, and (if successful) frees the object. More... | |
Blob API | |
| int64_t | c4blob_getSize (C4BlobStore *, C4BlobKey) |
| Gets the content size of a blob given its key. More... | |
| C4SliceResult | c4blob_getContents (C4BlobStore *, C4BlobKey, C4Error *) |
| Reads the entire contents of a blob into memory. More... | |
| C4StringResult | c4blob_getFilePath (C4BlobStore *, C4BlobKey, C4Error *) |
| Returns the path of the file that stores the blob, if possible. More... | |
| C4BlobKey | c4blob_computeKey (C4Slice contents) |
| Derives the key of the given data, without storing it. More... | |
| bool | c4blob_create (C4BlobStore *store, C4Slice contents, const C4BlobKey *expectedKey, C4BlobKey *outKey, C4Error *error) |
| Stores a blob. More... | |
| bool | c4blob_delete (C4BlobStore *, C4BlobKey, C4Error *) |
| Deletes a blob from the store given its key. More... | |
Streamed Reads | |
| typedef struct c4ReadStream | C4ReadStream |
| An open stream for reading data from a blob. More... | |
| C4ReadStream * | c4blob_openReadStream (C4BlobStore *, C4BlobKey, C4Error *) |
| Opens a blob for reading, as a random-access byte stream. More... | |
| size_t | c4stream_read (C4ReadStream *stream, void *buffer, size_t maxBytesToRead, C4Error *error) |
| Reads from an open stream. More... | |
| int64_t | c4stream_getLength (C4ReadStream *, C4Error *) |
| Returns the exact length in bytes of the stream. More... | |
| bool | c4stream_seek (C4ReadStream *, uint64_t position, C4Error *) |
| Moves to a random location in the stream; the next c4stream_read call will read from that location. More... | |
| void | c4stream_close (C4ReadStream *) |
| Closes a read-stream. More... | |
Streamed Writes | |
| typedef struct c4WriteStream | C4WriteStream |
| An open stream for writing data to a blob. More... | |
| C4WriteStream * | c4blob_openWriteStream (C4BlobStore *, C4Error *) |
| Opens a write stream for creating a new blob. More... | |
| bool | c4stream_write (C4WriteStream *, const void *bytes, size_t length, C4Error *) |
| Writes data to a stream. More... | |
| C4BlobKey | c4stream_computeBlobKey (C4WriteStream *) |
| Computes the blob-key (digest) of the data written to the stream. More... | |
| bool | c4stream_install (C4WriteStream *, const C4BlobKey *expectedKey, C4Error *) |
| Adds the data written to the stream as a finished blob to the store. More... | |
| void | c4stream_closeWriter (C4WriteStream *) |
| Closes a blob write-stream. More... | |
| typedef struct c4BlobStore C4BlobStore |
Opaque handle for an object that manages storage of blobs.
| typedef struct c4ReadStream C4ReadStream |
An open stream for reading data from a blob.
| typedef struct c4WriteStream C4WriteStream |
An open stream for writing data to a blob.
Derives the key of the given data, without storing it.
| bool c4blob_create | ( | C4BlobStore * | store, |
| C4Slice | contents, | ||
| const C4BlobKey * | expectedKey, | ||
| C4BlobKey * | outKey, | ||
| C4Error * | error | ||
| ) |
Stores a blob.
The associated key will be written to outKey
. If expectedKey
is not NULL, then the operation will fail unless the contents actually have that key.
| bool c4blob_delete | ( | C4BlobStore * | , |
| C4BlobKey | , | ||
| C4Error * | |||
| ) |
Deletes a blob from the store given its key.
| bool c4blob_deleteStore | ( | C4BlobStore * | , |
| C4Error * | |||
| ) |
Deletes the BlobStore's blobs and directory, and (if successful) frees the object.
| void c4blob_freeStore | ( | C4BlobStore * | ) |
Closes/frees a BlobStore.
(A NULL parameter is allowed.)
| C4SliceResult c4blob_getContents | ( | C4BlobStore * | , |
| C4BlobKey | , | ||
| C4Error * | |||
| ) |
Reads the entire contents of a blob into memory.
Caller is responsible for freeing it.
| C4StringResult c4blob_getFilePath | ( | C4BlobStore * | , |
| C4BlobKey | , | ||
| C4Error * | |||
| ) |
Returns the path of the file that stores the blob, if possible.
This call may fail with error kC4ErrorWrongFormat if the blob is encrypted (in which case the file would be unreadable by the caller) or with kC4ErrorUnsupported if for some implementation reason the blob isn't stored as a standalone file. Thus, the caller MUST use this function only as an optimization, and fall back to reading the contents via the API if it fails. Also, it goes without saying that the caller MUST not modify the file!
| int64_t c4blob_getSize | ( | C4BlobStore * | , |
| C4BlobKey | |||
| ) |
Gets the content size of a blob given its key.
Returns -1 if it doesn't exist. WARNING: If the blob is encrypted, the return value is a conservative estimate that may be up to 16 bytes larger than the actual size.
Decodes a string of the form "sha1-"+base64 into a raw key.
| C4StringResult c4blob_keyToString | ( | C4BlobKey | ) |
Encodes a blob key to a string of the form "sha1-"+base64.
| C4ReadStream* c4blob_openReadStream | ( | C4BlobStore * | , |
| C4BlobKey | , | ||
| C4Error * | |||
| ) |
Opens a blob for reading, as a random-access byte stream.
| C4BlobStore* c4blob_openStore | ( | C4String | dirPath, |
| C4DatabaseFlags | flags, | ||
| const C4EncryptionKey * | encryptionKey, | ||
| C4Error * | outError | ||
| ) |
Opens a BlobStore in a directory.
If the flags allow creating, the directory will be created if necessary. Call c4blob_freeStore() when finished using the BlobStore.
| dirPath | The filesystem path of the directory holding the attachments. |
| flags | Specifies options like create, read-only |
| encryptionKey | Optional encryption algorithm & key |
| outError | Error is returned here |
| C4WriteStream* c4blob_openWriteStream | ( | C4BlobStore * | , |
| C4Error * | |||
| ) |
Opens a write stream for creating a new blob.
You should then call c4stream_write to write the data, ending with c4stream_install to compute the blob's key and add it to the store, and then c4stream_closeWriter.
| C4BlobStore* c4db_getBlobStore | ( | C4Database * | db, |
| C4Error * | outError | ||
| ) |
Returns the BlobStore associated with a bundled database.
Fails if the database is not bundled. DO NOT call c4blob_freeStore on this! The C4Database will free it when it closes.
| void c4stream_close | ( | C4ReadStream * | ) |
Closes a read-stream.
(A NULL parameter is allowed.)
| void c4stream_closeWriter | ( | C4WriteStream * | ) |
Closes a blob write-stream.
If c4stream_install was not already called (or was called but failed), the temporary file will be deleted without adding the blob to the store. (A NULL parameter is allowed, and is a no-op.)
| C4BlobKey c4stream_computeBlobKey | ( | C4WriteStream * | ) |
Computes the blob-key (digest) of the data written to the stream.
This should only be called after writing the entire data. No more data can be written after this call.
| int64_t c4stream_getLength | ( | C4ReadStream * | , |
| C4Error * | |||
| ) |
Returns the exact length in bytes of the stream.
| bool c4stream_install | ( | C4WriteStream * | , |
| const C4BlobKey * | expectedKey, | ||
| C4Error * | |||
| ) |
Adds the data written to the stream as a finished blob to the store.
If expectedKey
is not NULL, then the operation will fail unless the contents actually have that key. (If you don't know ahead of time what the key should be, call c4stream_computeBlobKey beforehand to derive it, and pass NULL for expectedKey.) This function does not close the writer.
| size_t c4stream_read | ( | C4ReadStream * | stream, |
| void * | buffer, | ||
| size_t | maxBytesToRead, | ||
| C4Error * | error | ||
| ) |
Reads from an open stream.
| stream | The open stream to read from |
| buffer | Where to copy the read data to |
| maxBytesToRead | The maximum number of bytes to read to the buffer |
| error | Error is returned here |
| bool c4stream_seek | ( | C4ReadStream * | , |
| uint64_t | position, | ||
| C4Error * | |||
| ) |
Moves to a random location in the stream; the next c4stream_read call will read from that location.
| bool c4stream_write | ( | C4WriteStream * | , |
| const void * | bytes, | ||
| size_t | length, | ||
| C4Error * | |||
| ) |
Writes data to a stream.


Managing Connections Using the PHP SDK with Couchbase Server
This section describes how to connect the PHP SDK to a Couchbase cluster and bucket. It contains best practices as well as information on the connection string, SSL and other advanced connection options.
To manage Couchbase Server connections, you need to configure the client, connect to a bucket, and configure SSL.
Configuring the Client
To configure the client, instantiate a new Cluster
object:
$myCluster = new CouchbaseCluster('couchbase://<IP_ADDRESS>,<IP_ADDRESS>,<IP_ADDRESS>');
In addition to the connection string passed to the Cluster
object, you can include a username and password.
The username and password are required to perform management operations against your cluster.
If you do not use the cluster management aspects of the SDK, the username and password parameters are optional.
Keep in mind that these credentials are the same ones you use to log in to the Couchbase administrator console, not those specified for the bucket itself.
|
From Couchbase PHP SDK 2.5.0 (using libcouchbase 2.9.2), If using Docker Swarm, or otherwise running the SDK inside the NAT, then you will want to disable with Note that any SSL/TLS certificates must be set up at the point where the connections are being made. The Couchbase SDKs will honor any valid SSL/TLS certificates. |
Authentication
Regular authentication is where you provide a password to the openBucket()
and manager()
methods.
It is also possible to define all credentials in single place, and associate with a container, which can be used for all future connections.
Since version 2.3.0, the PHP SDK provides the interface \Couchbase\Authenticator
which is implemented by all credentials containers.
The library can pull authentication parameters from it when necessary.
At the moment there is only one implementation of this interface: \Couchbase\ClassicAuthenticator
, but upcoming releases will also have RBAC support.
The use of the authenticator is simple:
$authenticator = new \Couchbase\ClassicAuthenticator();
$authenticator->cluster('Administrator', 'password');
$authenticator->bucket('protected', 'secret');
$cluster = new \Couchbase\Cluster("couchbase://localhost");
$cluster->authenticate($authenticator);
$cluster->openBucket('protected'); // successfully opens connection
$cluster->manager()->createBucket('hello'); // automatically use admin credentials
It is still possible to provide a password to the openBucket()
or manager()
method, which will take precedence over the authenticator.
Such behaviour is discouraged, and future implementations of the \Couchbase\Authenticator
interface are likely to prevent mixing of authentication sources.
You can shortcut using the authenticator()
method, if you don’t need to reuse the credentials in several instances of authenticate()
, replacing it with authenticateAs()
:
$cluster = new CouchbaseCluster("couchbase://localhost");
$cluster->authenticateAs('Administrator', 'password');
Connecting to a Bucket
To connect to a bucket, call the openBucket()
method against your Cluster
instance, passing in the name of the bucket that you want to connect to.
If no bucket name is specified, the default bucket is opened.
The following example shows how to connect to a bucket:
$myCluster = new CouchbaseCluster();
$myBucket = $myCluster->openBucket('default');
In addition to the bucket name, you can optionally include the bucket password if one has been defined, as shown in the following example:
$myCluster = new CouchbaseCluster();
$myBucket = $myCluster->openBucket('default', 'password');
Disconnecting from a Bucket
To close the connection to a bucket, call its disconnect()
method.
This method queues the disconnection of all open connections and causes any pending operations to fail.
Scalability and concurrency
Creating a new Bucket
object is relatively expensive, and keeping many idle Bucket
objects will negatively impact server performance (if done at a large scale).
PHP SDK by default uses persistent connections to reuse underlying IO objects if the connection strings are the same.