Suppose we have a code snippet that looks like:
|
|
Before reading further, please stop and go through the code snippet carefully.
Now, What output do you expect from the above snippet? There is a high probability (unless you are a Python wizard!) that you might expect the output to be
Well, if that’s what you expected, then you are wrong!
The correct output is
Interesting isn’t it? Let’s dig a little deeper and find out why this happens.
Perhaps, it’s quite known now.
Expressions in default arguments are calculated when the function is defined, not when it’s called.
Before I explain further, let’s verify the above statement quickly:
For me the output looks like
Clearly, arg
was calculated when time_func
was defined and not when it’s called otherwise you would expect arg
to be different each time it’s executed.
Coming to our func
example. When def
statement is executed a new function object is created, bound to the name func
and stored in the namespace of the module. Within the function object, for each argument object with a default value, an object is created that holds the default value.
In the above example, a string object (“Hello!”) and an empty dictionary object is created as a default for default_immutable_arg
and default_mutable_arg
respectively.
Now, whenever func
is called without arguments, the arguments will use the values from their default bounded object i.e default_immutable_arg
will always be “Hello!” but default_mutable_arg
may change. It’s because of the fact that string objects are immutable whereas a dictionary objects are mutable. So whenever in line 4, we append “!” to default_immutable_arg
, a new string object is created and returned which is then printed in next line, keeping default string object’s value still intact.
This isn’t the case with mutable dictionary objects. The first time we execute func
without any arguments, default_mutable_arg
takes its value from default dictionary object which is {}
now. Hence, the else
block will be executed. Since the dictionary objects are mutable, the else
block changes the default dictionary object. So in the next execution of the function, when default_mutable_arg
reads from default dictionary object, it receives {'some_key':'some_value'}
and not {}
. Interesting huh? Well that’s the explanation! :)
Don’t use the mutable argument objects as default arguments! Simple! So how do we improve our func
? Well, just use None
as default argument value and check for None
inside function body to determine if the arguments were passed or not.
Now, you can imagine what would happen if we overlook this feature in defining class methods. Clearly, all the class instances will share the same references to the same object which isn’t something you’d want to have in the first place! :)
I hope that was fun,
Cheers!
]]>Alright folks. It’s officially an end to the amazing 12 weeks of Google Summer of Code 2016! These 12 weeks have certainly helped me become a better person, both personally and professionally. I’ve had a chance to interact and learn from some very interesting and amazing minds from coala. Sadly, I couldn’t meet all but a few of them during the EuroPython conference this summer.
First and foremost, I would like to pay my eternal gratitude to my mentor Attila Tovt who patiently helped me improve the patch through multiple reviews. I was learning something new with each iteration. The major take away for me from his mentorship would be:
There is always a hack to something, then there is a solution to it.
Sadly, I couldn’t meet him during EuroPython conference, but I am hopeful to pay my regards in person someday! :)
Next, I must thank Abdeali for helping and guiding when I started my journey with coala and also Lasse Schuirmann. Well after all he is coala’s BDFL! Wondering what that means? Benevolent Dictator for Life :D
Hmm, on a serious note, if I say I am going to continue contributing to coala or any other FOSS that I may come across in future, one of the major reasons and an influencer would be Lasse! The guy is totally amazing. I don’t think anything else could describe him better than his own words that he said during EuroPython’16
Guys! Don’t just be a participant. It’s boring! Create a conference!
Impressive isn’t it? That’s Lasse for you! :)
I would also thank fellow GSoC students and now my new friends - Adrian, Adhithya, Alex, Karan, Araf, Sanket and Abhay. I look forward to stay in touch with them even after GSoC! :)
Last but far from the least, thanks to Max for giving such a wonderful lightning talk at EuroPython’16, cooking for us with all love at Bilbao, for being such an amazing and wonderful person.
The acknowledgement must end with my gratitude to coala, Google and Python Software Foundation for giving me an opportunity to be a GSoC student in the first place.
Past summer, I’ve contributed and maintained coala-html and coala-website projects. The commits and live demos are available online.
Project | Commits | Status |
---|---|---|
coala-html demo | coala-html commits, total 49 commits | completed |
coala website repo and coala embedded in coala-website demo | Mentioned in Table 2 | It is almost complete, but requires improvement in design. |
Commits for coala website repository as Gitlab doesn’t support commit filtering by author yet.
Commit SHA | Shortlog |
---|---|
244a0b | Add coala config, .gitignore and README |
f9242a | runserver.py: Init setup with flask |
36f064 | server: Add editor and preloader |
51ac6e | bower.json: Use bower to install dependencies |
ac3cdd | beardoc: Display what coala can do interactively |
dd4f27 | layout.html: Add donation, about and sponsor |
1b1efa | index.html: Add gitter chat |
f90513 | bear-doc: Include bear-doc |
597a2a | route.py: Add contributors |
9a3491 | requirements.txt: Add python dependencies |
432f4f | README.md: Add Installation instructions |
220020 | sitemap: Add sitemap_template |
bd31c1 | editor.html: Add editor |
Although GSoC period may end, my contributions to FOSS won’t! :)
Regards,
Tushar
Pipes are the eldest IPC tools and were introduced by Douglas McIlroy after he noticed that most of the time they were processing the output of one process as the input to another. Later, Ken Thompson added the concept of pipes to the UNIX operating system.
In simple terms, a pipe is a method of connecting the standard output of one process to the standard input of another. A quick example:
In the above shell command (reading from left to right), we are passing the output from ls
command as an input to sort
command. The combined output is a current directory’s content in a sorted order. The vertical bar ( |
) is a pipe character. It acts as a method of one-way communications (or half-duplex) between processes.
They are of basically two types : Anonymous Pipes and Named Pipes (FIFO).
The one we just saw, was an anonymous pipe or half-duplex pipe.
When a process creates a pipe, the kernel sets up two file descriptors (read and write) for use by the pipe. A pipe initially connects a process to itself and any data traveling through the pipe moves through the kernel. Under Linux, pipes are actually represented internally with a valid inode which resides within the kernel itself, and not within the bounds of any physical file system. Well, you might question, what’s the point of pipe if they connect a process to itself. Are they just going to communicate with itself? Well, the answer is no. Pipes are useful in case when we fork a child process and as we know a child process inherits any open file descriptors from parent, allowing us to setup a multiprocess communication (in this case between child and parent process). As both the processes have access to file descriptors, a pipeline is setup.
One important thing we should note that, since the pipe resides within the confines of the kernel, any process that is not in the ancestry for the creator of the pipe has no way of addressing it. This is not the case with named pipes (FIFOS), which we will discuss next.
Unlike anonymous pipes, a named pipe exists in the file system. After input-output has been performed by the sharing processes, the pipe still exists in the file system independently of the process, and can be used for communication between some other processes.
We can create a named pipes either using mkfifo
or mknod
shell commands (Python has an inbuilt method which we will see during implementations).
Just like a regular file, we can set file permissions on a named pipe. Checkout mode from man mkfifo
.
A quick example of named pipes that we might have often come across.
Here, the output from ls -li
is redirected to a temporary named pipe, which shell creates, names and later deletes. Another fun example is to create a very basic shared terminal. Let’s try it out.
The idea is to create a named pipe and then use two separate cat
process to read/write data from/to the named pipe.
Creating a named pipe (from console) :
|
|
If you observer closely the output from ls -l
looks like:
|
|
You may have noticed an additional |
character is shown next to named_pipe_file_name
and the file permission starts with p
. This is a Linux clue that the named_pipe_file_name
is a pipe.
Using it:
|
|
You might notice that after the first command the execution appears to be blocked. This happens because the other end of the pipe is not yet connected, and so the kernel suspends the first process until the second process opens the pipe.
I hope that was a very simple usage of named pipes and helped you understand named pipes.
Now (for fun), let’s implement pipes in Python. Since the code is in Python, I need not explain every line from the code. It should be readable. :)
The basic idea is to create two processes (parent and child) and let parent read the data written by child process.
Anonymous pipe
|
|
Named pipe
The implementation is almost similar except the fact that instead of descriptors, we have access to named pipe file name and we use it to perform I/O operations.
|
|
Phew! That was fun!
Cheers!
]]>Recently, I attended EuroPython conference at Bilbao, Spain where I had a chance to meet a few cool fellow coalaians ( @sils1297, @sims1253, @Udayan12167, @justuswilhelm, @Redridge, @Adrianzatreanu and @hypothesist ) and over thousand Pythonista | Pythoneer who happened to share their love and experience using Python by presenting talks, lightning talks or training session. Sadly, I couldn’t meet Attila Tovt my amazing GSoC mentor.
Being my first PyCon ever, I was a little nervous but curious about it. Having spent a day with the community made me feel comfortable. Seeing the energy that people shared, I was overwhelmed! In the coming days, mornings started with a Keynote speaker which was then followed by over dozen talks throughout a day on various exciting topics like Descriptors in Python, Effective Code Review, AsyncIO, Algorithmic Trading with Python, Deep Learning with tensorflow, Gilectomy: overcoming the GIL in CPython implementation by Lary Hastings and many more.
Finally the exploration ended with the workshop which I conducted on Guide to make a real contribution to an open source project for novice. It was a learning experience and definitely memorable for me! Being the first time in Europe, I was excited. People are friendly and the place is truly beautiful! :)
Well, it has been totally an amazing and learning experience during this summer. I could effectively learn the best practices for a collaborative programmer and (probably) became one! Credits to my mentor - @Uran198 who patiently and solicitously reviewed my PRs. I never really bothered to follow practices like atomic changes , TDD aiming for maximum coverage for good code quality until I started contributing. Honestly, following such practices seemed bloating and sometimes annoying at first but once I got hold of them, they became a habit. I think during the GSoC period, the crucial things that I have learnt are how to write a code that is maintainable (docstrings, effective and atomic commits), testable (efficient code design, writing unittests and impressive coverage) and follows the standards. Having learnt these skills, I look forward to share them with my friends and the community.
The coming blogs would cover these practices in details. :)
11 weeks are over with a week remaining before submissions. coala-html project is ready with this PR. I shall be working on to improve this project even after my GSoC period is over. Apart from coala-html, coala-website is almost ready with minor design stuff remaining. Soon enough I will submit it for review. :)
Cheers!
]]>Since past couple of days I’ve been attending the EuroPython conference at Bilbao, Spain and it has been an increíble experience so far! There are over a dozen amazing talks with something new to share every day and the super fun lightning talks at the end of the day. If for some reason you weren’t able to attend the conference then you may see the talks live at EuroPython YouTube channel.
In this blog I would like to talk briefly about PEP498 - Literal String Interpolation in Python. Python supports multiple ways to format text strings (%
-formatting, format
formatting and Templates
). Each of these are useful in some ways but they do lack in other aspects. For eg. the simplest version of format
style is too verbose.
1 | place = “Bilbao, Spain” |
Clearly, there is a redundancy. place is being used multiple times. Similarly, %
formatting is limited with the types (int
, str
, double
) that can be parsed.
f-strings are proposed in PEP498. f-strings are basically a literal strings with ‘f’ or ‘F’ as prefix. It embeds expressions using braces that are evaluated at runtime. Let’s see some simple examples:
1 | place = “Bilbao, Spain” |
I think that’s simpler and better than other string formatting options. If this feature interests you and you want to learn more about it then I recommend checking out the PEP498 documentation.
Cheers!
]]>Now post mid-term, I’ve started working on a new website for coala. Beside having a new UI, it will also have an editor integrated where users can upload a code snippet (presently, Python, JavaScript, Perl, Java, PHP only) and let coala run static code analysis on the file. Eventually, user gets the feedback. Some of the desired features are:
The features appear cool but should be little tricky to implement. The challenging part is to automatically generate the coafile based on the settings and also apply the patch upon analysis. Also, I shall implement more features as I progress.
May the CSS be with me! :)
Also, coming week I shall be conducting an online workshop - mostly to cover version control and workflow. Many new comers struggle in this area. I am hopeful that this workshop will help them learn the skills that are much needed and get them started quickly. Details to follow. :)
Stay tuned!
]]>We would love to hear from you. If you have any feature proposal or if you find any bugs, please let us know
Now, with coala-html released I’ve started working on coala website. Further updates in next blog!
:)
Originally, TDD meant writing tests before the actual implementation. ( But you may write tests afterwards too (not a good approach though). Now, the question comes - how can one write tests for something that haven’t been implemented yet. Makes sense, isn’t it? Well usually when you test modules/functions , you already know your expectations. For instance, If I am going to write a function that checks if a given real number is a power of 2, I already know the outcome. In this case it’s a boolean value - True
for power of 2 and False
otherwise. So, you may very well write tests using this information.
There are many advantages of adopting TDD. First being avoiding Regression bugs. Regression bug is a bug that had been fixed in the past and then occurred again. For instance, we change obviously unrelated piece of code and therefore we do not check some old problem, because we do not expect that problem to occur again. Once we have an automated test for this bug, it will not happen again because we can easily run all tests instead of manually trying only the parts that are obviously related to the change we made.
Another reason being Refactoring. The code architecture may require changes to a project requirements. Tests prove whether the code still works, even after a major refactoring.
You may install karma using npm
- node package manager. To install the Karma plugins for Mocha and Chai. Also, it’d be nice to use PhantomJS for headless testing. Let’s create a pacakge.json
file and add the dependencies to it. It might look like:
1 | { |
Now, run npm install
to fetch and install the dependencies.
Also, to make it easier to run karma from the command line you can install karma-cli
globally, which will run the local version without having to specify the path to karma (node node_modules/karma/bin/karma):
1 | npm install -g karma-cli |
Karma needs a configuration file. Create one by running karma init
and answering the simple question. Make sure you specify Mocha
as your testing framework. Also, mention source and tests files location accordingly. In my case it’s in ./app/**/*.js
for source and ./tests/**/*Spec.js
for tests.
Let’s create two empty files app/powerOfTwo.js
and tests/powerOfTwoSpec.js
. It’d look like
1 | ├── app |
Once you’re done, you have karma-conf.js
. To get Chai included in the test pipeline, edit karma-conf.js and add it to the frameworks setting. Also to be able to use PhantomJS mention it in browsers
.
1 | frameworks: [‘mocha’, ‘chai’] |
Running karma start
will execute the default karma-conf.js. You can have multiple configuration files which can be run by specifying the name of the configuration file. karma start <conf-file-name>
.
Enough installation. Let’s get down to writing tests.
By default, you can use Mocha’s assertion module (which is in fact Node’s regular assertion module) to run your tests. However, it can be quite limiting. This is where assertion libraries like Chai enter the frame. Writing a test is like constructing a perfect sentence in English. Don’t believe me? Hm see yourself. We describe an umbrella of tests, and state some expected outputs for various tests under that umbrella.
Write this in tests/powerOfTwoSpec.js
.
1 | describe(‘powerOfTwo’, function(){ // The Umbrella test. You can create as many depending on your code architecture |
Note that we haven’t created the powerOfTwo
function yet. But looking at the tests, we can say how our function is expected to behave. That’s TDD and BDD for you in the simplest form.
Now let’s write our powerOfTwo function in powerOfTwo.js
1 | var powerOfTwo = function(num) { |
Finally, we may run the tests running npm test
in project root directory.
I hope that was simple and introduced you to the basics of TDD/BDD. Go ahead and try yourself.
Explore more at
Cheers! :)
]]>coala-html is a console application that runs coala analysis and generates an interactive webpage for the user.
coala-html, creates a webpage (Angular app) based on certain json files that are generated - first time when coala-html is run on a given repository, or updated - running coala-html again. By default, the generated webpage is served by launching a server at localhost and the json files are updated. User has an option to change this behaviour by providing the nolaunch
and noupdate
arguments respectively while running the coala-html. User can also provide an optional dir
or directory path argument that will store the code for the webpage.
You may see a brief demo below:
Now as the basic functionalities are done, I am gonna work on improving the UI and writing more tests for having maximum coverage in coming weeks.
Stay tuned! :)
]]>So before our script executes, we will have Brush tool selected. We could handle the selection of brush tool but it all depends on the position of the brush tool in Paint and it differs for various Paint softwares.
So let’s get started.
Importing required modules. Nothing cool here.
1 | import math |
Ideally, we would want to have control over our automation script even in situations when things go wrong. We could ask script to wait after every function call, giving us a short window to take control of the mouse and keyboard if something goes wrong.
This pause after each function call can be implemented by setting a certain numeric value to PAUSE constant in pyautogui module.
1 | pyautogui.PAUSE = 1 # Pause for 1 seconds after every function call |
We may also want to add an initial delay to let user select an appropriate paint tool.
1 | time.sleep(5) |
Screen size can be obtained using size
method. If you observer carefully, Symbol of Peace
is a big circle enclosing an inverted Y
. Circular path can be traced using parametric equation. Let us assume screen center as circle center.
1 | cx, cy = pyautogui.size() # center for circle |
Mouse clicks can be implemented using pyautogui.click method. A mouse click is a combination of the two events:
Both combined makes one click. pyautogui.click takes x and y coordinates of the region to click upon. If these params are not passed then a click is performed at the current mouse position.
Let’s implement mouse click to focus on the paint region.
1 | pyautogui.click(x,y) |
Apart from a click, we can also drag mouse cursor. PyAutoGUI provides the pyautogui.dragTo() and pyautogui.dragRel() functions to drag the mouse cursor to a new location or a location relative to its current one. dragTo takes x and y coordinate of the final position and dragRel takes x and y coordinates and interprets it relative to the current position.
The origin lies at top-left corner of screen and the x-coordinates increase going to the right, and the y-coordinates increase going down. All coordinates are positive integers; there are no negative coordinates.
Now next few lines would create a circular path with enclosed inverted Y
. The idea is to use parametric equation of circle and keep incrementing the angle until one complete revolution or 2*PI angle has been swept.
1 | while 2math.pi - angle >= 0.001: |
Combining all together
1 | import math |
You may try and run this script after selecting a brush tool.
Here is a Demo
Please note that this was only a brief introduction to GUI automation using Python. PyAutoGUI also provides a bunch of other functions like to perform hotkeys operations (Ctrl + c for copy) etc.
If you find this module interesting you should check out its documentation.
Cheers!
]]>The EuroPython conference series was initiated by the European Python community in 2002. It started in Charleroi, Belgium, which attracted over 200 attendees and have surpassed the 1000 attendee mark in 2014. It’s the second largest Python conference world-wide and the largest in Europe. If you are interested, you should buy the ticket as long as they last. :)
I shall be conducting a session on a guide to make a real contribution to an open source project for novice and also be accompanied by the awesome coalains who will be attending this conference. We have a sprint scheduled too. :D
I am grateful to the Python Software Foundation and EuroPython for sponsoring the accommodation and ticket for the conference. Without such aid it wouldn’t be possible to meet the awesome community out there. I must also pay my gratitude to Lasse Schuirmann for encouraging and helping to make this participation actually happen. :)
Stay tuned!
]]>Most people live - whether physically, intellectually or morally - in a very restricted circle of their potential being. We all have reservoirs of life to draw upon of which we do not dream.
William James
Since past few days, I have been reading The Monk Who Sold His Ferrari by Robin Sharma.
The author emphasises the importance of observing the beauty in the most ordinary things and talks about a mystical fable that contains the seven virtues for an enriched life.
The fable goes like:
Imagine, you are sitting in the middle of a magnificent, lush, green garden. This garden is filled with the most spectacular flowers you have ever seen. The environment is supremely tranquil and silent. Savor the sensual delights of this garden and feel as if you have all the time in the world to
enjoy this natural oasis. As you look around you see that in the center of this magical garden stands a towering, red lighthouse, six stories high. Suddenly, the silence of the garden is disturbed by a loud creaking as the door at the base of the lighthouse opens. Out stumbles a nine-foot-tall,
nine-hundred-pound Japanese sumo wrestler who casually wanders into the center of the garden. As this sumo wrestler starts to move around the garden, he finds a shiny gold stopwatch which someone had left behind many years earlier. He slips it on, and falls to the ground with an enormous thud. The sumo wrestler is rendered unconscious and lies there, silent and still. Just
when you think he has taken his last breath, the wrestler awakens, perhaps stirred by the fragrance of some fresh yellow roses blooming nearby. Energized, the wrestler jumps swiftly to his feet and intuitively looks to his left. He is startled at what he sees. Through the bushes at the very edge of the garden he observes a long winding path covered by millions of sparkling diamonds. Something seems to instruct the wrestler to take the path, and to his credit, he does. This path leads him down the road of everlasting joy and eternal bliss.
The author further explains that in the fable, the garden is a symbol for the mind and it is one of the seven timeless virtues for living a gratified life. If we care for our mind, if we nurture it and if we cultivate it just like a fertile, rich garden, it will blossom far beyond our expectations. But if we let the weeds take root, lasting peace of mind and deep inner harmony will always elude us.
Our life is highly influenced by the quality of our thoughts. Thoughts are paramount and little bundles of energy. The author recommends to care for our thoughts as if it being the most prized possessions. Negative thoughts or worries reduce the productivity of that twelve-pound mass sitting between our shoulders - Our Mind.
To summarize
I shall be sharing more as I further progress. :)
]]>Something was holding me back from taking the first step but finally, I’ve started writing blog. \m/
I am delighted to share the news that I’ve been recently selected as a Google Summer of Code intern and I shall be working with coala organisation under Python Software Foundation.
It all started with my participation in IndiaHack Open Source competition, a month long contest during January’16 and got introduced to coala.
I still remember, within a few hours after my first message at Gitter channel, I started working on an issue that was supposed to improve the coverage of coala core. Specifically, increase it from 98% to 100%. I had to first get familiar with the codebase, coala protocols like rebase - linear history, making atomic changes with good commit messages and writing a quality code. As I had just started, it was certainly a challenging task for me. But with the humble and ever supporting nature of coala developers, I got comfortable fairly soon.
I really look forward to continue as a contributor to this awesome community as a GSoC intern during summer and further.
Certainly, It has been a learning experience so far. I’ve learnt a lot since past couple of months. Getting inspired from another awesome coalaian - Sils1297, I shall be attending EuroPython 2016 at Bilbao, Spain coming July. My talk, Guide to make a real contribution to an open source project for novice can be seen at the website.
We also have a sprint planned during the conference.
Feel free to drop me a mail if you are attending the conference.
I guess that’s all for now. :)
Stay tuned for further updates!