• Home   /  
  • Archive by category "1"

Unchecked Assignment Intellij Python

I wrote this little piece a long time ago — it was last updated in May 2007. In 2009 I moved it from my website to this blog. At this point I consider it an historical artifact, in the sense that I consider it frozen; I’m no longer going to update it when, for example, Java acquires a new programmer-friendly feature.

During the years when it was on my web site, I received a number of email comments. I responded to them all, but no one — other than their authors and me — ever saw the comments and my responses. By moving this piece onto a blog, I hope that folks who feel like commenting can do so more easily, and can share their comments with a wider audience.

During the years when it was on my web site, virtually all of the comments that I received were from Java programmers. Some were calm and helpful, pointing out (for example) new programmer-friendly features of Java. Many were hot and angry and accused me of writing the piece for the sole purpose of bad-mouthing Java. If this describes you, please don’t fire off your angry counter-blast immediately. Go away, calm down, come back and read it again carefully.

I was recently asked if I still hold the opinions that I expressed in this article. I think that’s worth talking about… but in another post.

— Steve Ferg

Updated October 14, 2011 to fix a few minor typos

Note that this post has a companion post on the concepts of weak vs. strong, and static vs. dynamic, typing in programming languages.

Comparing Python and Java

A programmer can be significantly more productive in Python than in Java.

How much more productive? The most widely accepted estimate is 5-10 times. On the basis of my own personal experience with the two languages, I agree with this estimate.

Managers who are considering adding Python to their organization’s list of approved development tools, however, cannot afford to accept such reports uncritically. They need evidence, and some understanding of why programmers are making such claims. This page is for those managers.

On this page, I present a list of side-by-side comparisons of features of Java and Python. If you look at these comparisons, you can see why Python can be written much more quickly, and maintained much more easily, than Java. The list is not long — it is meant to be representative, not exhaustive.

This page looks only at programmer productivity, and does not attempt to compare Java and Python on any other basis. There is, however, one related topic that is virtually impossible to avoid. Python is a dynamically-typed language, and this feature is an important reason why programmers can be more productive with Python; they don’t have to deal with the overhead of Java’s static typing. So the debates about Java/Python productivity inevitably turn into debates about the comparative advantages and drawbacks of static typing versus dynamic typing — or strong typing versus weak typing — in programming languages. I will not discuss that issue here, other than to note that in the last five years a number of influential voices in the programming community have been expressing serious doubts about the supposed advantages of static typing.

For those who wish to pursue the matter, Strong versus Weak Typing: A Conversation with Guido van Rossum, Part V is a good place to start. See also Bruce Eckel’s weblog discussion Strong Typing vs. Strong Testing and Robert C. Martin’s weblog discussion Are Dynamic Languages Going to Replace Static Languages?. For background, see one of the papers that started it all in 1998 — Scripting: Higher Level Programming for the 21st Century by John Ousterhout.

Several of these discussions contain valuable comparisons of Java and Python. For other language comparisons, see the Python language comparisons page at www.python.org, and the PythonComparedToJava page at Python for Java Programmers.

Finally, it is important to note that asserting that a programmer can be more productive in Python than in Java, is not the same as asserting that one ought always to use Python and never to use Java. Programming languages are tools, and different tools are appropriate for different jobs. It is a poor workman whose toolbox contains only a hammer (no matter how big it is!), and it is a poor programmer (or software development organization) whose development toolkit contains only one programming language. Our toolboxes should contain both Python and Java, so that in any given situation we have the option of choosing the best tool for the job. So our claim is not that Python is the only programming language that you’ll ever need — only that the number of jobs for which Python is the best tool is much larger than is generally recognized.

Java vs. Python Productivity – an Overview

There are three main language characteristics that make programmers more productive with Python than with Java.

statically typed

In Java, all variable names (along with their types) must be explicitly declared. Attempting to assign an object of the wrong type to a variable name triggers a type exception.That’s what it means to say that Java is a statically typed language.

Java container objects (e.g. Vector and ArrayList) hold objects of the generic type Object, but cannot hold primitives such as int. To store an int in a Vector, you must first convert the int to an Integer. When you retrieve an object from a container, it doesn’t remember its type, and must be explicitly cast to the desired type.

dynamically typed

In Python, you never declare anything. An assignment statement binds a name to an object, and the object can be of any type. If a name is assigned to an object of one type, it may later be assigned to an object of a different type. That’s what it means to say that Python is a dynamically typed language.

Python container objects (e.g. lists and dictionaries) can hold objects of any type, including numbers and lists. When you retrieve an object from a container, it remembers its type, so no casting is required.

For more information on static vs. dynamic typing, see this post.


“abounding in words; using or containing more words than are necessary”

concise (akaterse)

“expressing much in a few words. Implies clean-cut brevity, attained by excision of the superfluous”

not compactcompact

In The New Hacker’s Dictionary, Eric S. Raymond gives the following definition for “compact”:

Compact adj. Of a design, describes the valuable property that it can all be apprehended at once in one’s head. This generally means the thing created from the design can be used with greater facility and fewer errors than an equivalent tool that is not compact.


The classic “Hello, world!” program illustrates the relative verbosity of Java.

public class HelloWorld { public static void main (String[] args) { System.out.println("Hello, world!"); } }print "Hello, world!"
print("Hello, world!") # Python version 3


In the following example, we initialize an integer to zero, then convert it to a string, then check to see if it is empty. Note the data declaration (highlighted), which is necessary in Java but not in Python. Notice also how verbose Java is, even in an operation as basic as comparing two strings for equality.

myCounter = 0; myString = String.valueOf(myCounter); if (myString.equals("0")) ...myCounter = 0 myString = str(myCounter) if myString == "0": ...
// print the integers from 1 to 9 for (int i = 1; i < 10; i++) { System.out.println(i); } print the integers from 1 to 9 for i in range(1,10): print i


Your application has 15 classes. (More precisely, it has 15 top-level public classes.)

Each top-level public class must be defined in its own file. If your application has 15 such classes, it has 15 files.Multiple classes can be defined in a single file. If your application has 15 classes, the entire application could be stored in a single file, although you would probably want to partition it sensibly into perhaps 4, 5, or 6 files.


In your application, method A calls B calls C calls D calls E calls F. You discover that F must throw exception SpecialException, and it must be caught by A.

You must throw SpecialException in F, and catch it in A.
You must add “throws SpecialException” to the signatures of methods B, C, D, E, and F.
You must raise SpecialException in F, and catch it in A.Exceptions will propagate upward automatically; there is nothing more that you must do.

The reason for this is that Java, virtually alone among object-oriented programming languages, uses checked exceptions — exceptions that must be caught or thrown by every method in which they might appear, or the code will fail to compile. Recently (as of June 2003) there seems to be an increasing amount of unhappiness with Java’s use of checked exceptions. See Bruce Eckel’s “Does Java need Checked Exceptions?” and Ron Waldhoff’s “Java’s checked exceptions were a mistake”.

As chromatic, the Technical Editor of the O’Reilly Network, put it:

I like the idea of checked exceptions in some situations, but forcing every method to deal with (catching or throwing) all exceptions that its child calls or may call can be tedious. I’d rather be able to ignore an exception and let it propagate upwards. Sometimes, I’d rather not worry about exceptions at all.


Your application has an Employee class. When an instance of Employee is created, the constructor may be passed one, two, or three arguments.

If you are programming in Java, this means that you write three constructors, with three different signatures. If you are programming in Python, you write only a single constructor, with default values for the optional arguments.

public class Employee { private String myEmployeeName; private int myTaxDeductions = 1; private String myMaritalStatus = "single"; //--------- constructor #1 ------------- public Employee(String EmployeName) { this(employeeName, 1); } //--------- constructor #2 ------------- public Employee(String EmployeName, int taxDeductions) { this(employeeName, taxDeductions, "single"); } //--------- constructor #3 ------------- public Employee(String EmployeName, int taxDeductions, String maritalStatus) { this.employeeName = employeeName; this.taxDeductions = taxDeductions; this.maritalStatus = maritalStatus; } ...class Employee(): def __init__(self, employeeName , taxDeductions=1 , maritalStatus="single" ): self.employeeName = employeeName self.taxDeductions = taxDeductions self.maritalStatus = maritalStatus ...

In Python, a class has only one constructor.

The constructor method is simply another method of the class, but one that has a special name:


In Why Python? Eric S. Raymond notes that:

Python … is compact — you can hold its entire feature set (and at least a concept index of its libraries) in your head.

In Why I Love Python Bruce Eckel notes that Java is not compact.

I can remember many Python idioms because they’re simpler. That’s one more reason I program faster [in Python]. I still have to look up how to open a file every time I do it in Java. In fact, most things in Java require me to look something up.

import java.io.*; ... BufferedReader myFile = new BufferedReader( new FileReader(argFilename));# open an input file myFile = open(argFilename)


Java’s string-handling capabilities are surprisingly weak. (But they have improved considerably with the addition of the split method to the String class in Java 1.4.)

Function or MethodJavaPython
Remove leading and trailing whitespace from string s
Remove leading whitespace from string s(not available)
Remove trailing whitespace from string s(not available)


Code to add an int to a Vector, and then retrieve it.

Prior to Java 1.5, a new Integer object had to be created and initialized from the int before it could be added to a Vector. In order to retrieve the value, the member of the Vector had to be cast back to an Integer, and then converted back to an int.

Java (before version 1.5)Python
public Vector aList = new Vector; public int aNumber = 5; public int anotherNumber; aList.addElement(new Integer(aNumber)); anotherNumber = ((Integer)aList.getElement(0)).intValue();aList = [] aNumber = 5 aList.append(aNumber) anotherNumber = aList[0]

This clumsiness was eliminated in Java 1.5 with the introduction of generics (which allows you to “type” a container object) and autoboxing (which automates conversion between primitive types and their corresponding wrapper classes). With generics, it is possible to code:

which reads as:

Java (after version 1.5)Python
public Vector<Integer> aList = new Vector<Integer>; public int aNumber = 5; public int anotherNumber; aList.addElement(aNumber); anotherNumber = aList.getElement(0);aList = [] aNumber = 5 aList.append(aNumber) anotherNumber = aList[0]


Verbosity is not just a matter of increasing the number of characters that must be typed — it is also a matter of increasing the number of places where mistakes can be made. The Java code on the left has 5 control characters: where the corresponding Python code has only one control character, the colon. (Or two, if you count indentation. See below.)

if ( a > b ){ a = b; b = c;}if a > b : a = b b = c

Omitting or duplicating such characters is easy to do accidentally, and constitutes a severe error in the code. In my personal estimate, I spend 5 times as much time fixing such errors in Java as I do in Python. It really cuts into your productivity — and your creative energy — when you spend that much of your time just trying to satisfy the compiler.

Technically, Python has another control character that Java does not — indentation. But the requirement for correct indentation is the same in Java as it is in Python, because in both languages correct indentation is a practical requirement for human-readable code. The Python interpreter automatically enforces correct indentation, whereas the Java compiler does not. With Java, you need an add-on product such as the Jalopy code formatter to provide automated
enforcement of indentation standards.


Thanks to Skip Montanaro, Chris Lawrence, Donald McCarthy, Bengt Richter, and Christian Pohlmann for helpful feedback on earlier versions of this page.

Like this:



This entry was posted in Java and Python. Bookmark the permalink.

How to Get Started with PyCharm and Have a Productive Python IDE

The whole Editors versus IDEs debate is getting old and boring, especially because it is not a zero sum game. I’ve been using Emacs for 15+ years and at one point I used it to read my email, browse the web, and make coffee (haven’t we all?). But today I find that I’m more productive by using the right tool for the right job.

Powerful editors like Emacs and Vim are fantastic. I find it puzzling that some editors or IDEs perform basic operations such as search and replace clunkily while Vim and Emacs get it just right.

And yet a search for terms like “Vim as a Python IDE” or “Emacs as a Python IDE” returns hundreds of thousands of links, which shows that people want features such as smart completion, code navigation, and project support. To give you one data point, one of my most popular posts is “how to configure Emacs as a Python IDE”, even if it’s six years old and out-of-date.

PyCharm is one of the most popular IDEs for Python and it’s packed with great features. In this post I will show how to get started with PyCharm quickly to have a productive Python development environment. I’m using PyCharm 3.0.2 Professional Edition on the Mac (they have an open-source version as well). I use a heavily modified default keymap (it also has Emacs and Vim keymaps). I suggest you check the official Mac and the Windows/Linux reference cards for the default shortcuts.

Initial Customization

When you start PyCharm for the first time it asks what keymap and theme you want to use. I don’t like its Emacs keymap, so I use the default Mac OS X keymap and customize the shortcuts I want:

If this is the first time you are using PyCharm and don’t have a configuration to import you may want to click on “Configure” in the welcome screen to set some basic things:

I like to show the line numbers and method separators (Editor→Appearance→Show method separators, Show line numbers):

Also, I like the Solarized theme. I install it by following the instructions and select it as the default theme in Editor→Colors & Fonts. Solarized light for IntelliJ has some weird colors choices (for instance, it uses gray for the default text instead of a crisper black), so I change it on Editor→Colors & Fonts→General. My advice is not to be afraid to change the colors to something you like. You can export your settings in case you need to re-install PyCharm.

Compared to some IDEs, I find PyCharm visually clean, and if you want an even cleaner UI, you can hide the toolbar, the tool buttons, the navigation bar, and the status bar (on the View menu):

Virtualenv and the Python Interpreter

You can create new projects with File→New Project or open an existing project with File→Open Directory. PyCharm supports many types of Python projects such as Django or Flask out-of-the-box. For this post I’ll create a simple project to test the pyquery library (I’ll choose the “Empty project”).

You need to tell PyCharm what Python interpreter you want to use since it can use a different interpreter for each project. It will use this information to index all available libraries. A good practice is to have one virtualenv for each project. You can either use an existing virtualenv or create a new one from PyCharm (Settings→Project Interpreter→Python Interpreters).

For this project I’ll create a new virtualenv and make it available to all projects:

You can quickly search, read the description, and install packages from PyCharm. This is nothing you couldn’t do on the terminal, but it’s very convenient to be able to search for packages without leaving your IDE.

Some packages may take a while to install, especially if they need to be compiled. PyCharm runs the installation in background and you can see what is happening by clicking on the status bar:

As we can see, it installed not only , but its dependencies as well, such as lxml (as we would expect):


PyCharm is no Vim, but you can do a lot by using only the keyboard. You can assign shortcuts to dozens (if not hundreds) of actions in Settings→Keymap. I change the default keymap pretty heavily since I like to have shortcuts like Control-a, Control-e, Control-k, and Control-y that are default in any Cocoa text box but are not setup by default in the “Mac OS X” keymap. You can also define mouse shortcuts. For instance, I changed Quick Documentation to use Option-Click. If you are a Vim user you may want tot try IdeaVim, a Vim emulator plugin. I heard good things about it, but I didn’t have the chance to try it yet.

I use the Dvorak keyboard layout, and annoyingly, there’s a bug where the wrong keys are used. People have reported this problem with French Canadian and German layouts as well. This means that I have to rebind quite a few shortcuts just to avoid this problem.

PyCharm uses function keys such as F1 and F2 a lot. As you probably know, on the Mac the top keys work as “multimedia” keys by default and as function keys by pressing the Fn key. We can swap this behavior in System Preferences→Keyboard.

I like to be able control the sound volume and change the brightness without having to reach for the Fn key, but I also like to use the function keys while programming without reaching for the Fn key (I’m lazy, what can I say?). I use Palua to switch between the “multimedia” and function keys. You can switch with a global key or you can configure Palua to switch automatically when using a specific application. I use the multimedia keys for all applications (the default) and configure Palua to use the Function keys for Xcode and PyCharm.

External Editor

PyCharm can launch any external tool, so I configure it to open Emacs with the current file. This is useful when you want to do some quick editing that is faster with your favorite editor (Emacs, Vim, TextMate, etc).

Go to Settings→External Tools, make sure “Open console” is unchecked and insert the path to the Program, the Parameters (in this case we can get the full file name with ) and the Working directory ().

You can assign it to a shortcut:

And now it’s available from the menu as well.

Running Code and the REPL

There are many ways to run our code with PyCharm. We can use the venerable print function (or statement, depending on your Python version), import code on the REPL, send code to the console, use the debugger, or use IPython on a terminal.

The Venerable Print

Using to display values is a useful and widely used technique, but it can lead to messy code if not used carefully.

We can run the code by clicking on the “play” button or with Control-R if the file is already selected to run.

If the file is not selected to run, with can select and run it with Control-Option-R or by right clicking and selecting from the context menu. PyCharm will remember your choice and you can use Control-R the next time. It sounds complicated but it is really simple. Check the manual for more information.

Console and REPL

My favorite way is to run the code on the REPL. You can open a Python console inside PyCharm on Tools→Run Python Console (I’ve assigned it to Control-C Control-C). It’ll use IPython if available (I recommend you install IPython inside the virtualenv) and will add the path of the current file to Python’s path. On the console you can import the functions you want to execute as usual.

Completion is available in the console as well:

Having imported the function, we can run it as usual. And we can toggle the console visibility easily with ⌘–4.

Execute Selection in Console

If the code I want to run is more than a couple of one-liners and not formal enough to write unit tests (I may be playing with data, for instance) I may save it in a scratch file. We can select the code we want to run (usually I just select the whole file with ⌘-A) and pick “Execute Selection in Console” from the context menu (or, even better, use the keyboard shortcut). [I omitted some menu items in the screenshot to make it shorter].

In the following example the variable is available in the console since we have selected the whole file to be executed in the console:


It would be nice if we could send the whole file to the console in one operation. Fortunately, we can record a macro. Select Edit→Macros→Start Macro Recording and perform the operations as before (select the whole file, send the selection to console, switch to the console). As you can see, my macro has only four actions (I press the down arrow key to remove the selection):

After you record the macro it’s available in the Macros menu and you can assign a shortcut to it (I use Control-C Control-E, but for some reason PyCharm only shows the first half of shortcuts with two strokes).


Many people like to use the debugger to inspect data. Even if I prefer to use the REPL, sometimes the debugger is just more efficient, especially when inspecting complex objects. PyCharm doesn’t allow you to set a breakpoint on an empty line, so in this short example I had to add an extra line (I used , but I could have used ) since I wanted the debug to stop after setting the variable. In real-life code this is seldom necessary.

Vanilla IPython

Finally, there’s nothing wrong with running an external terminal with IPython and using features such as and autoreload.

Finding Commands

It’s easy to get overwhelmed with so many commands. If you use PyCharm on the Mac you can use Help→Search as usual, or you can use Help→Find Action in any platform. It allows you to search for any PyCharm command, including the ones not available from the menu. (Emacs addicts will note this is somewhat similar to Emacs’ M-x). This is very useful and powerful and I use it all the time.

Code completion

Completion in PyCharm is top notch. By default PyCharm will suggest things while you are typing:

Since this feature can be a little power hungry, you can disable it by selecting File→Power Save Mode. You can still use completion by calling it explicitly with Control-Space.

When completing, you can narrow the suggestion list by typing a substring:

Or you can type only the first letters of CammelCaseClasses or function_names_with_underscores:

If you type Control-Space once PyCharm will try to list the most related items:

If you type Control-Space again it will list every name it knows. This can be overwhelming, but notice it is listing the function from the unimported file.

But often you just want to complete the name of a local variable in one of the opened buffers. This feature has been available in Emacs and Vim for ages and now it’s available in PyCharm as well. The manual calls it Hippie Completion, but the actual command name (that is, the name you will find in Find Action) is “Cyclic Expand Word” and in my tests it’s working even inside docstrings.

Completion may not work in some cases when a library doesn’t have type hints. This StackOverflow page suggests to set a breakpoint in pdb and list the possible attributes with . One similar solution is to create a breakpoint in PyCharm and evaluate an expression at the breakpoint by clicking on the last icon in the debug toolbar (or using the appropriate keyboard shortcut). In this case I evaluated the expression “dir®”.

Access to documentation

PyCharm has three ways to access documentation: Quick Definition, Quick Documentation, External Documentation, and Parameter Info. You can access them from the View menu or from the respective shortcuts.

Quick definition will show the whole definition (duh!) of a symbol (class, method, function, etc), including the documentation, of course. It’s useful when you just want to take a quick look at the definition without jumping to it.

Quick documentation will show the symbol’s documentation and signature.

Finally, External Documentation, and Parameter Info are pretty straightforward. The first opens the documentation in the default browser and the second shows the parameter information for a function or method (useful to quick check the name of keyword arguments, for instance).

The external documentation works out-of-the-box with Python (of course), PyQt4, PySide, gtk, wx, numpy, scipy, and kivy and you can add the path for external documentation in Settings→Python External Documentation.

Code quality

PyCharm checks if your code conforms to PEP8 while you are typing. It’ll let you know if you have too many spaces or blank lines, if you are using underscores instead of CamelCase for classes names, and so on. If you want, you can configure PyCharm to run pylint as an external tool, as well.

Finding your way in the source code

PyCharm’s power starts when you master its navigation commands. It can jump to classes, functions, and so on. You can jump to the definition of a class, method, function, or variable quickly with ⌘-B or ⌘-Click on a Mac or Ctrl-B or Control-Click on Windows and Linux.

The mechanism to navigate to a class, file, or symbol is pretty much the same. You are presented with a dialog where you can type a substring, include items outside your project, and filter the results if necessary. Go to the Navigate menu or use the appropriate keyboard shortcut:

This is a typical dialog to navigate to a Class definition:

You can enter part of the name, including the file extension. For instance, if you want to open a JavaScript in a Django project but don’t remember its name, you can search for “.js”.

These features allow us to navigate the source code very quickly. Let’s suppose we are studying the Django source code and we want to see how the function is implemented. We don’t know where it’s defined, so we go to Navigate→Symbol (⌥-⌘-O), type “render” and pick the first option (we can see it’s defined in ). If we have hidden the navigation bar we can show it quickly with Navigate→Jump to the Navigation Bar (⌘-↑) and see where the file is located (django→django→shortcuts.py):

Sometimes it’s useful to filter the completion results to take out things you are not interested. In the following example I remove the results related to JavaScript to have a much cleaner completion list:

PyCharm allows you to fold blocks such as classes, methods, and functions, but you can create your own foldable regions. This is useful when it makes sense to group things (classes, methods, functions, etc) in one bigger block. These blocks can be folded allowing us to focus on particular regions of the code. You can list all regions in a file by going to Navigate→Custom Region or using the appropriate keyboard shortcut. Sadly there’s no way to list all regions in a project.

Unit tests

Before we can run a test we need to add a new Run/Debug configuration. We go to Run→Edit Configurations and click on the plus button on the top left corner. Then, we select “Python tests” and the test runner. For this example I’ll use Unittests:

Finally, we need to add the folder where the tests are and pick the right Python interpreter:

Now we can run our tests just like we run code: by clicking in the toolbar or by selecting Run→Run (Control-⌥-R). This will open a dialog where you can choose what you want to run (you may have other things to run). You can run all tests or only the test on the cursor.

After you run the tests, PyCharm will remember your last choice, so you can repeat it with Control-R. This is useful if you are fixing one particular test case and want to run it multiple times without running the other tests. You don’t need to have the cursor on the test file you want to run; you can run the tests from any file. You can go from the code to its test by selecting Navigate→Test (or appropriate hotkeys).

Dealing with multiple files

As you noticed, PyCharm uses one tab per file:

To switch to tabs we can use the commands Select Next Tab and Select Previous Tab. They are bound to Control-→ and Control-← by default, but OS X uses these keys, so I rebind them to Control-⌘-N

and Control-⌘-P (I use the same shortcuts to switch tabs in the Terminal).

One more direct approach to go to a tab is to use Navigate→File as we’ve seen, or View→Recent Files (⌘-E) and View→Recently Changed Files (⇧-⌘-E). These last two commands will present a list of files where you can click on type a substring to narrow the selection. In the following example I only had to type “⌘-E”, “s”, “enter” to go to the tab with the file:

Split Windows

PyCharm has support for split windows. It’s not as advanced as in Emacs and Vim but it’s useful enough.

No command to deal with split windows have shortcuts assigned to them by default, so you’ll have to do it yourself. These are the keys that I use:

  • Split Vertically, Control-S
  • Split Horizontally, Control-H
  • Unsplit, Control-C Control-U
  • Unsplit All, Control-C Control-A
  • Goto Next Splitter, Control-C Control-N
  • Goto Previous Splitter, Control-C Control-P
  • Move to Opposite Group, Control-C Control-M

Move to Opposite Group will move a tab to another group, but it only works if we have only two panes. In this case it’s just easier to drag and drop the tab to the desired place.


PyCharm can do a lot for us out-of-the-box. We saw how to use virtualenv, define shortcuts, use an external editor, run code, define macros, find commands with Find Action, be productive with code completion, access documentation, navigate the source code, run unit tests, and deal with multiple files and split windows.

And we are just scratching the surface. We didn’t talk about editing, version control, plugins, debugging (local and remote), templates, using TextMate bundles, web development, and much more.

I suggest you check PyCharm’s official documentation, including the Quickstart Guide and the Online Help. Also, Andrew Brookins wrote a very good PyCharm review from a Vim’s user perspective. I recommend it even if you don’t use Vim.

One thought on “Unchecked Assignment Intellij Python

Leave a comment

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *