Are 0.0 and 1.0 considered magic numbers? - java

I know that -1, 0, 1, and 2 are exceptions to the magic number rule. However I was wondering if the same is true for when they are floats. Do I have to initialize a final variable for them or can I just use them directly in my program.
I am using it as a percentage in a class. If the input is less than 0.0 or greater than 1.0 then I want it set the percentage automatically to zero. So if (0.0 <= input && input <= 1.0).
Thank you

Those numbers aren't really exceptions to the magic number rule. The common sense rule (as far as there is "one" rule), when it isn't simplified to the level of dogma, is basically, "Don't use numbers in a context that doesn't make their meaning obvious." It just so happens that these four numbers are very commonly used in obvious contexts. That doesn't mean they're the only numbers where this applies, e.g. if I have:
long kilometersToMeters(int km) { return km * 1000L; }
there is really no point in naming the number: it's obvious from the tiny context that it's a conversion factor. On the other hand, if I do this in some low-level code:
sendCommandToDevice(1);
it's still wrong, because that should be a constant kResetCommand = 1 or something like it.
So whether 0.0 and 1.0 should be replaced by a constant completely depends on the context.

It really depends on the context. The whole point of avoiding magic numbers is to maintain the readability of your code. Use your best judgement, or provide us with some context so that we may use ours.
Magic numbers are [u]nique values with unexplained meaning or multiple occurrences which could (preferably) be replaced with named constants.
http://en.wikipedia.org/wiki/Magic_number_(programming)
Edit: When to document code with variables names vs. when to just use a number is a hotly debated topic. My opinion is that of the author of the Wiki article linked above: if the meaning is not immediately obvious and it occurs multiple times in your code, use a named constant. If it only occurs once, just comment the code.
If you are interested in other people's (strongly biased) opinions, read
What is self-documenting code and can it replace well documented code?

Usually, every rule has exceptions (and this one too). It is a matter of style to use some mnemonic names for these constants.
For example:
int Rows = 2;
int Cols = 2;
Is a pretty valid example where usage of raw values will be misleading.
The meaning of the magic number should be obvious from the context. If it is not - give the thing a name.

Attaching a name for something creates an identity. Given the definitions
const double Moe = 2.0;
const double Joe = 2.0;
...
double Larry = Moe;
double Harry = Moe;
double Garry = Joe;
the use of symbols for Moe and Joe suggests that the default value of Larry and Harry are related to each other in a way that the default value of Garry is not. The decision of whether or not to define a name for a particular constant shouldn't depend upon the value of that constant, but rather whether it will non-coincidentally appear multiple places in the code. If one is communicating with a remote device which requires that a particular byte value be sent to it to trigger a reset, I would consider:
void ResetDevice()
{
// The 0xF9 command is described in the REMOTE_RESET section of the
// Frobnitz 9000 manual
transmitByte(0xF9);
}
... elsewhere
myDevice.ResetDevice();
...
otherDevice.ResetDevice();
to be in many cases superior to
// The 0xF9 command is described in the REMOTE_RESET section of the
// Frobnitz 9000 manual
const int FrobnitzResetCode = 0xF9;
... elsewhere
myDevice.transmitByte(FrobnitzResetCode );
...
otherDevice.transmitByte(FrobnitzResetCode );
The value 0xF9 has no real meaning outside the context of resetting the Frobnitz 9000 device. Unless there is some reason why outside code should prefer to send the necessary value itself rather than calling a ResetDevice method, the constant should have no value to any code outside the method. While one could perhaps use
void ResetDevice()
{
// The 0xF9 command is described in the REMOTE_RESET section of the
// Frobnitz 9000 manual
int FrobnitzResetCode = 0xF9;
transmitByte(FrobnitzResetCode);
}
there's really not much point to defining a name for something which is in such a narrow context.
The only thing "special" about values like 0 and 1 is that used significantly more often than other constants like e.g. 23 in cases where they have no domain-specific identity outside the context where they are used. If one is using a function which requires that the first parameter indicates the number of additional parameters (somewhat common in C) it's better to say:
output_multiple_strings(4, "Bob", Joe, Larry, "Fred"); // There are 4 arguments
...
output_multiple_strings(4, "George", Fred, "James", Lucy); // There are 4 arguments
than
#define NUMBER_OF_STRINGS 4 // There are 4 arguments
output_multiple_strings(NUMBER_OF_STRINGS, "Bob", Joe, Larry, "Fred");
...
output_multiple_strings(NUMBER_OF_STRINGS, "George", Fred, "James", Lucy);
The latter statement implies a stronger connection between the value passed to the first method and the value passed to the second, than exists between the value passed to the first method and anything else in that method call. Among other things, if one of the calls needs to be changed to pass 5 arguments, it would be unclear in the second code sample what should be changed to allow that. By contrast, in the former sample, the constant "4" should be changed to "5".

Related

Unexpected Identifier Expected Error [duplicate]

Why in java (I dont know any other programming languages) can an identifier not start with a number and why are the following declarations also not allowed?
int :b;
int -d;
int e#;
int .f;
int 7g;
Generally you put that kind of limitation in for two reasons:
It's a pain to parse electronically.
It's a pain for humans to parse.
Consider the following code snippet:
int d, -d;
d = 3;
-d = 2;
d = -d;
If -d is a legal identifier, then which value does d have at the end? -3 or 2? It's ambiguous.
Also consider:
int 2e10f, f;
2e10f = 20;
f = 2e10f;
What value does f have at the end? This is also ambiguous.
Also, it's a pain to read either way. If someone declares 2ex10, is that a typo for two million or a variable name?
Making sure that identifiers start with letters means that the only language items they can conflict with are reserved keywords.
That's because section 3.8 of the Java Language Specification says so.
An identifier is an unlimited-length
sequence of Java letters and Java
digits, the first of which must be a
Java letter. An identifier cannot have
the same spelling (Unicode character
sequence) as a keyword (§3.9), boolean
literal (§3.10.3), or the null literal
(§3.10.7).
As for why this decision was made: probably because this simplifies parsing, avoids ambiguous grammar, allows introduction of special syntax in a later version of the language and/or for historical reasons (i.e. because most other languages have the same restrictionsimilar restrictions). Note that your examples example with -d is especially clear:
int -d = 7;
System.out.println("Some number: " + (8 + -d));
Is the minus the first part of an identifier, or the unary minus?
Furthermore, if you had both -d and d as variables, it would be completely ambiguous:
int -d = 7;
int d = 2;
System.out.println("Some number: " + (8 + -d));
Is the result 15 or 6?
I don't know exactly but i think that's because numbers are used to represent literal values, so when the compiler find a token that starts with a number, it knows it is dealing with a literal. if an identifier could start with a number, the compiler would need to use a look ahead to find the next character in the token to find out if it is an identifier or a literal.
Such things aren't allowed in just about any language (I can't think of one right now), mostly to prevent confusion.
Your example -d is an excellent example. How does the compiler know if you meant "the variable named -d" or "the negative of the number in the variable d"? Since it can't tell (or worse yet, it could so you couldn't be sure what would happened when you typed that without reading the rest of the file), it's not allowed.
The example 7g is the same thing. You can specify numbers as certain bases or types by adding letters to the end. The number 8357 is an int in Java, where as 8357L is a long (since there is an 'L' on the end). If variables could start with numbers, there would be cases where you couldn't tell if it was supposed to be a variable name or just a literal.
I would assume the others you listed have similar reasons behind them, some of which may be historical (i.e. C couldn't do it for reason X, and Java is designed to look like C so they kept the rule).
In practice, they are almost never a problem. It's very rare you find a situation where such things are annoying. The one you'll run into the most is variables starting with numbers, but you can always just spell them out (i.e. oneThing, twoThing, threeThing, etc.).
Languages could allow some of these things, but this simplifying assumption makes it easier on the compiler writer, and on you, the programmer, to read the program.
Parsers are (usually) written to break the source text into "tokens" first. An identifier that starts with a number looks like a number. Besides 5e3, is a valid number (5000.0) in some languages.
Meanwhile : and . are tokenized as operators. In some contexts an identifier that starts with one of these would lead to ambiguous code. And so forth.
Every language needs to define what is a valid character for an identifier and what is not. Part of the consideration is going to be ease of parsing, part is going to be to avoid ambiguity (in other words even a perfect parsing algorithm couldn't be sure all the time), part is going to be the preference of the language design (in Java's case similarity with C, C++) and some is just going to be arbitrary.
The point is it has to be something, so this is what it is.
For example, are there not numerous times we wish to have objects with these names?
2ndInning
3rdBase
4thDim
7thDay
But imagine when someone might try to have a variable with the name 666:
int 666 = 777;
float 666F = 777F;
char 0xFF = 0xFF;
int a = 666; // is it 666 the variable or the literal value?
float b = 666F // is it 666F the variable or the literal value?
Perhaps, one way we might think is that variables that begin with a numeral must end with an alphabet - so long as
it does not start with 0x and end with a letter used as a hexadeciamal digit, or
it does not end with characters such as L or F,
etc, etc.
But such rules would make it really difficult for programmers as Yogi Berra had quipped about - how could you think and hit at the same time? You are trying to write a computer programme as quickly and error free as possible and then you would have to bother with all these little bits and pieces of rules. I would rather, as a programmer, have a simple rule on how variables should be named.
In my efforts using lexers and regexp to parse data logs and data streams for insertion into databases, I have not found having a keyword or variable beginning with a numeral would make it anymore difficult to parse - so long there are as short a path as possible to remove ambiguity.
Therefore, it is not so much as making it easier for the compiler but for the programmer.

The difference between arrays in Java and C

In my book there is an example which explains the differences between arrays in Java and C.
In Java we can create an array by writing:
int[] a = new int[5];
This just allocates storage space on the stack for five integers and we can access them exactly as we would have done in Java
int a[5] = {0};
int i;
for (i = 0, i < 5; i++){
printf("%2d: %7d\n", i, a[i]);
}
Then the author says the following
Of course our program should not use a number 5 as we did on several places in the example, instead we use a constant. We can use the C preprocessor to do this:
#define SIZE 5
What are advantages of defining a constant SIZE 5?
Using a named constant is generally considered good practice because if it is used in multiple places, you only need to change the definition to change the value, rather than change every occurrence - which is error prone.
For example, as mentioned by stark in the comments, it is likely that you'll want to loop over an array. If the size of the array is defined by a named constant called SIZE, then you can use that in the loop bounds. Changing the size of the array then only requires changing the definition of SIZE.
There is also the question of whether #define is really the right solution.
To borrow another comment, from Jonathan Leffer: see static const vs #define vs enum for a discussion of different ways of naming constants. While modern C does allow using a variable as an array size specifier, this technically results in a variable-length array which may incur a small overhead.
You should use a constant, because embedding magic numbers in code makes it harder to read and maintain. For instance, if you see 52 in some code, you don't know what it is. However, if you write #define DECKSIZE 52, then whenever you see DECKSIZE, you know exactly what it means. In addition, if you want to change the deck size, say 36 for durak, you could simply change one line, instead of changing every instance throughout the code base.
Well, imagine that you create a static array of 5 integer just like you did int my_arr [5]; ,you code a whole programm with it, but.. suddenly you realise that maybe you need more space. Imagine that you wrote a code of 6-700 lines, you MUST replace every occurence of you array with the fixed number of your choice. Every for loop, and everything that is related with the size of this array. You can avoid all of this using the preprocessor command #define which will replace every occurence of a "keyword" with the content you want, it's like a synonymous for something. Eg: #define SIZE 5 will replace in your code every occurence of the word SIZE with the value 5.
I find comments here to be superflous. As long as you use your constant (5 in this case) only once, it doesn't matter where it is. Moreover, having it in place improves readability. And you certainly do not need to use the constant in more than one place - afterall, you should infer the size of array through sizeof operator anyways. The benefit of sizeof approach is that it works seamlessly with VLAs.
The drawback of global #define (or any other global name) is that it pollutes global namespace. One should understand that global names is a resource to be used conservatively.
#define SIZE 5
This looks like an old outdated way of declaring constants in C code that was popular in dinosaur era. I suppose some lovers of this style are still alive.
The preferred way to declare constants in C languages nowadays is:
const int kSize = 5;

How many objects are created by using the Integer wrapper class?

Integer i = 3;
i = i + 1;
Integer j = i;
j = i + j;
How many objects are created as a result of the statements in the sample code above and why? Is there any IDE in which we can see how many objects are created (maybe in a debug mode)?
The answer, surprisingly, is zero.
All the Integers from -128 to +127 are pre-computed by the JVM.
Your code creates references to these existing objects.
The strictly correct answer is that the number of Integer objects created is indeterminate. It could be between 0 and 3, or 2561 or even more2, depending on
the Java platform3,
whether this is the first time that this code is executed, and
(potentially) whether other code that relies on boxing of int values runs before it4.
The Integer values for -128 to 127 are not strictly required to be precomputed. In fact, JLS 5.1.7 which specified the Boxing conversion says this:
If the value p being boxed is an integer literal of type int between -128 and 127 inclusive (§3.10.1) ... then let a and b be the results of any two boxing conversions of p. It is always the case that a == b.
Two things to note:
The JLS only requires this for >>literals<<.
The JLS does not mandate eager caching of the values. Lazy caching also satisfies the JLS's behavioral requirements.
Even the javadoc for Integer.valueof(int) does not specify that the results are cached eagerly.
If we examine the Java SE source code for java.lang.Integer from Java 6 through 8, it is clear that the current Java SE implementation strategy is to precompute the values. However, for various reasons (see above) that is still not enough to allow us to give a definite answer to the "how many objects" question.
1 - It could be 256 if execution of the above code triggers class initialization for Integer in a version of Java where the cache is eagerly initialized during class initialization.
2 - It could be even more, if the cache is larger than the JVM spec requires. The cache size can be increased via a JVM option in some versions of Java.
3 - In addition to the platform's general approach to implementing boxing, a compiler could spot that some or all of the computation could be done at compile time or optimized it away entirely.
4 - Such code could trigger either lazy or eager initialization of the integer cache.
First of all: The answer you are looking for is 0, as others already mentioned.
But let's go a bit deeper. As Stephen menthioned it depends on the time you execute it. Because the cache is actually lazy initialized.
If you look at the documentation of java.lang.Integer.IntegerCache:
The cache is initialized on first usage.
This means that if it is the first time you call any Integer you actually create:
256 Integer Objects (or more: see below)
1 Object for the Array to store the Integers
Let's ignore the Objects needed for Store the Class (and Methods / Fields). They are anyway stored in the metaspace.
From the second time on you call them, you create 0 Objects.
Things get more funny once you make the numbers a bit higher. E.g. by the following example:
Integer i = 1500;
Valid options here are: 0, 1 or any number between 1629 to 2147483776 (this time only counting the created Integer-values.
Why? The answer is given in the next sentence of Integer-Cache definition:
The size of the cache may be controlled by the -XX:AutoBoxCacheMax= option.
So you actually can vary the size of the cache which is implemented.
Which means you can reach for above line:
1: new Object if your cache is smaller than 1500
0: new Objects if your cache has been initialized before and contains 1500
1629: new (Integer) - Objects if your cache is set to exactly 1500 and has not been initialized yet. Then Integer-values from -128 to 1500 will be created.
As in the sentence above you reach any amount of integer Objects here up to: Integer.MAX_VALUE + 129, which is the mentioned: 2147483776.
Keep in mind: This is only guaranteed on Oracle / Open JDK (i checked Version 7 and 8)
As you can see the completely correct answer is not so easy to get. But just saying 0 will make people happy.
PS: using the menthoned parameter can make the following statement true: Integer.valueOf(1500) == 1500
The compiler unboxes the Integer objects to ints to do arithmetic with them by calling intValue() on them, and it calls Integer.valueOf to box the int results when they are assigned to Integer variables, so your example is equivalent to:
Integer i = Integer.valueOf(3);
i = Integer.valueOf(i.intValue() + 1);
Integer j = i;
j = Integer.valueOf(i.intValue() + j.intValue());
The assignment j = i; is a completely normal object reference assignment which creates no new objects. It does no boxing or unboxing, and doesn't need to as Integer objects are immutable.
The valueOf method is allowed to cache objects and return the same instance each time for a particular number. It is required to cache ints −128 through +127. For your starting number of i = 3, all the numbers are small and guaranteed to be cached, so the number of objects that need to be created is 0. Strictly speaking, valueOf is allowed to cache instances lazily rather than having them all pre-generated, so the example might still create objects the first time, but if the code is run repeatedly during a program the number of objects created each time on average approaches 0.
What if you start with a larger number whose instances will not be cached (e.g., i = 300)? Then each valueOf call must create one new Integer object, and the total number of objects created each time is 3.
(Or, maybe it's still zero, or maybe it's millions. Remember that compilers and virtual machines are allowed to rewrite code for performance or implementation reasons, so long as its behavior is not otherwise changed. So it could delete the above code entirely if you don't use the result. Or if you try to print j, it could realize that j will always end up with the same constant value after the above snippet, and thus do all the arithmetic at compile time, and print a constant value. The actual amount of work done behind the scenes to run your code is always an implementation detail.)
You can debug the Integer.valueOf(int i) method to find out it by yourself.
This method is called by the autoboxing process by the compiler.

Compare Code Submissions with Previous Submissions?

Users submit code (mainly java) on my site to solve simple programming challenges, but sending the code to a server to compile and execute it can sometimes take more than 10 seconds.
To speed up this process, I plan to first check the submissions database to see if equivalent code has been submitted before. I realize this will cause Random methods to always return the same result, but that doesn't matter much. Is there any other potential problem that could be caused by not running the code?
To find matches, I remove comments and whitespace when comparing code. However, the same code can still be written in different ways, such as with different variable names. Is there a way to compare code that will find more equivalent code?
You could store a SHA1 hash of the code to compare with a previous submission. You are right that different variable names would give different hashes. Try running the code through a minifier or obfuscator. That way, variable cat and dog will both end up like a1, then you could see if they are unique. The only other way would be to actually compile it into bytecode, but then it's too late.
Instead of analyzing the source code, why not speed up the compilation? Try having a servlet container always running with a custom ClassLoader, and use the JDK tools.jar to compile on the fly. You could even submit the code via AJAX REST and get the results back the same way.
Consider how Eclipse compiles your files in the background.
Also, consider how http://ideone.com implements their online compiler.
FYI It is a big security risk to allow random code execution. You have to be very careful about hackers.
Variable names:
You can write code to match variable names in one file with the variable names in the other, then you can replace both sets with a consistent variable name.
File 1:
var1 += this(var1 - 1);
File 2:
sum += this(sum - 1);
After you read File 1, you look for what variable name File 2 is using in the place of sum, then make the variable names the same across both files.
*Note, if variables are used in similar ways you may get incorrect substitutions. This is most likely when variables are being declared. To help mitigate this, you can start searching for variable names at the bottom of the file and work up.
Short hands:
Force {} and () braces into each if/else/for/while/etc...
rewrite operations like "i+=..." as "i=i+..."
Functions:
In cases where function order doesn't matter, you can make sure functions are equivalent and then ignore them.
Operator precedence:
"3 + (2 * 4)" is usually equivalent to "2 * 4 + 3"
A way around this could be by determining the precedence of each operation and then matching it to an operation of the same precedence in the other set of code. Once a set of operations have been matched, you can replace them with a variable to represent them.
Ex.
(2+4) * 3 + (2+6) * 5 == someotherequation
//substitute most precedent: (2+4) and (2+6) for a and b
... a * 3 + b * 5
//substitute most precedent: (a*3) and (b*5) for c and d
... c + d
//substitute most precedent....
These are just a couple ways I could think of. If you do it this way, it'll end up being quite a big project... especially if you're working with multiple languages.

Programming in Python vs. programming in Java

I've been writing Java for the last couple of years , and now I've started to write in python (in addition).
The problem is that when I look at my Python code it looks like someone tried to hammer Java code into a python format , and it comes out crappy because - well , python ain't Java.
Any tips on how to escape this pattern of "Writing Java in Python"?
Thanks!
You might consider immersing yourself in the Python paradigms. The best way is to first know what they are then explore the best practices by reading some literature and reviewing some code samples. I recommend Learning Python by Mark Lutz; great for beginners and advanced users.
You'll do yourself a great injustice if you program with Python and fail to leverage all of the built-in, developer-friendly, Pythonic syntax.
As my French teacher used to say, "French isn't just English with different words."
If you are new to Python and coming from Java (or C#, or other similar statically typed OO language), these classic articles from PJ Eby and Ryan Tomayko are necessary reading:
Python Is Not Java (PJE)
Java is not Python, either (PJE)
Python Interfaces are not Java Interfaces (PJE)
The Static Method Thing (Tomayko)
Getters/Setters/Fuxors (Tomayko)
You could start by reading The Zen of Python. It'll give you some insight into how Python code is supposed to be written, provided you understand the language enough to understand what it's talking about. :-)
Some of the major ways in which Python differs from C/Java-like languages are:
List comprehensions.
Support for functional programming.
The use of certain Pythonic constructs instead of similar C-like constructs although both seem to work (list comprehensions can be argued to be a part of this, but there are others).
There are others, but these are the main ones that bugged me when I first started Python (and I had come from years of Java like you).
Before using any of these, it is helpful to understand why you should go for pythonic code rather than the usual C/Java way in Python, although both give you the same output.
For starters, Python provides some powerful features not available in C/Java that makes your code much clearer and simpler (although this is subjective, and might not look any better to someone coming from Java at first). The first two points fall into this category.
For example, support for functions as first class objects and closures makes it easy to do things that would need all kinds of weird acrobatics with inner classes in Java.
But a major reason is that Python is an interpreted language, and certain constructs are much faster than the equivalent C/Java-like code. For example, list comprehensions are usually a lot faster than an equivalent for-loop that iterates over the indices of a list and accesses each item by index. This is a very objective benefit, and IMHO a lot of the "Python in way too slow" way of thinking comes from using Java-style code shoe-horned into Python.
One of the best ways to learn about pythonic code is to read other people's code. I actually learnt a lot by looking at Python code posted in answers to SO questions. These often come with explanations and it is usually obvious why it is better than non-pythonic code (speed, clarity, etc.).
Edit:
Of course, there are other ways of getting other people's code. You can also download and look through the code of any good open source Python project. Books are also a good resource, I would recommend O'Reilly Python Cookbook. It has lots of useful code examples and very detailed explanations.
1) Python supports many (but not all) aspects of
object-oriented programming; but it is
possible to write a Python program without
making any use of OO concepts.
1) Java supports only object-oriented
programming.
2) Python is designed to be used interpretively.
A Python statement may be entered at the
interpreter prompt
(>>>)
, and will be executed
immediately. (Implementations make some
use of automatic compilation into bytecodes
(.pyc files).
2) Programs written in Java must be explicitly
compiled into bytecodes (.class files),
though an IDE may do this automatically in a
way that is transparent to the user. Java does
not support direct execution of statements -
though there are tools like Dr. Java that
support this.
3) Python is dynamically typed:
• A variable is introduced by assigning a
value to it. Example:
someVariable = 42
• A variable that has been assigned a value of
a given type may later be assigned a value
of a different type. Example:
someVariable = 42
someVariable = 'Hello, world'
3) Java is
statically typed
:
• A variable must be explicitly declared to be
of some type before assigning a value to it,
though declaration and assignment may be
done at the same time. Examples:
int someVariable;
int someVariable = 42;
• A variable that has been declared to be of a
particular type may not be assigned a value
of a different type.
4) Python supports the following built-in data
types:
Plain integers (normally 32-bit integers in
the range -2147483648 through
2147483647).
• Long integers (size limited only by memory
size of the machine running on)
• Booleans (False and True).
• Real numbers.
• Complex numbers.
In addition, Python supports a number of
types that represent a collection of values -
including strings, lists, and dictionaries.
4) Java has two kinds of data types: primitive
types and reference types. Java supports the
following primitive data types:
• byte - 8-bit integers
• short - 16-bit integers
• int - 32-bit integers
• long - 64-bit integers (Java also supports a
class java.math.BigInteger to represent
integers whose size is limited only by
memory)
• float - 32-bit real numbers.
• double - 32-bit real numbers.
• boolean - (false and true).
• char - a single character.
In addition, Java supports arrays of any type
as the reference types, and the API includes
the class String and a large number of classes
used for collections of values.
5)
Python is line-oriented:
statements end at the
end of a line unless the line break is explicitly
escaped with . There is no way to put more
than one statement on a single line.
Examples:
this is a statement
this is another statement
this is a long statement that extends over more \
than one line
5)
Statements in Java always end with a
semicolon (;)
. It is possible for a statement to
run over more than one line, or to have
multiple statements on a single line.
Examples:
this is a statement;
this is another statement;
this is a long statement that extends over more
than one line;
a statement; another; another;
6)
Python comments begin with #
and extend to
the end of the line. Example:
This is a comment
A new statement starts here
6) Java has two kinds of comments. A comment
beginning with // extend to the end of the
line (like Python comments). Comments can
also begin with /* and end with */. These
can extend over multiple lines or be
embedded within a single line. Examples:
// This is a comment
A new statement starts here
/* This is also a comment */
/* And this is also a comment, which is
long enough to require several lines
to say it. */
Statement starts /* comment */ then continues
7) Python strings can be enclosed in either single
or double quotes (' or ""). A character is
represented by a string of length 1. Examples:
'This is a string'
"This is also a string" # Equivalent
'c' # A string
"c" # An equivalent string
Python uses the following operators for
constructing compound boolean expressions:
and, or and not. Example:
not(x > 0 and y > 0) or z > 0
7) Java strings must be enclosed in double
quotes (""). A character is a different type of
object and is enclosed in single quotes (').
Examples:
"This is a String"
'c' // A character, but not a String
Java uses the following operators for
constructing compound boolean expressions:
&&, ||, ! and ^ (meaning exclusive or)
Example:
! (x > 0 && y > 0) || z > 0 ^ w > 0
8) In Python, the comparison operators
(>, <, >=, <=, == and !=) can be applied to numbers
,
strings, and other types of objects), and
compare values in some appropriate way (e.g.
numeric order, lexical order) where possible.
8) In Java, most of the comparison operators
( >, <, >=, and <=) can be applied only to
primitive types. Two (== and !=) can be
applied to any object, but when applied to
reference types they test for same (different)
object rather than same (different) value.
9) There is no universally-accepted Python
convention for naming classes, variables,
functions etc.
9) By convention, most names in Java use mixed
case. Class names begin with an uppercase
letter; variable and function names begin with
a lowercase letter. Class constants are named
using all uppercase letters with underscores.
Examples:
AClassName
aVariableName
aFunctionName()
A_CLASS_CONSTANT
10) Python definite looping statements have the
form for variable in expression: Example:
for p in pixels:
something
10) Java has two kinds of definite looping
statements. One has the form
for (variable in collection) Example:
for (p in pixels)
something;
11) Python uses the built-in function range() with
for to loop over a range of integers.
Examples:
for i in range(1, 10)
something
(i takes on values 1, 2, 3, 4, 5, 6, 7, 8, 9)
for i in range(1, 10, 2)
something
(i takes on values 1, 3, 5, 7, 9)
11) Java uses a different form of the for to loop
over a range of integers. Examples:
for (int i = 1; i < 10; i ++)
something;
(i takes on values 1, 2, 3, 4, 5, 6, 7, 8, 9)
for (int i = 1; i < 10; i += 2)
something;
(i takes on values 1, 3, 5, 7, 9)
12) Python conditional statements have the form
if condition: and an optional else part has the
form else:. The form elif condition: is
allowed as an alternative to an else:
immediately followed by an if. Examples:
if x < 0:
something
if x < 0:
something
else:
something different
if x < 0:
something
elif x > 0:
something different
else:
yet another thing
12) Java conditional statements have the form
if (condition) and an optional else part has
the form else (no colon) There is no elif
form - else if is used directly. Examples:
if (x < 0)
something;
if (x < 0)
something;
else
something different;
if (x < 0)
something;
else if (x > 0)
something different;
else
yet another thing;
13) The scope of a Python conditional or looping
statement is denoted by indentation. (If
multiple lines are to be included, care must be
used to be sure every line is indented
identically). Examples:
if x < 0:
do something
do another thing regardless of the value of x
if x < 0:
do something
do something else
do yet a third thing
do another thing regardless of the value of x
13) The scope of a Java conditional or looping
statement is normally just the next statement.
Indentation is ignored by the compiler
(though stylistically it is still highly desirable
for the benefit of a human reader). If
multiple lines are to be included, the scope
must be delimited by curly braces ({ , }).
(Optionally, these can be used even if the
scope is a single line.) Examples:
if (x < 0)
do something;
do another thing regardless of the value of x;
if (x < 0)
do something; // Bad style-don't do this!
do another thing regardless of the value of x;
if (x < 0)
{
do something;
do something else;
do yet a third thing;
}
do another thing regardless of the value of x;
if (x < 0)
{
do something;
}
do another thing regardless of the value of x;
If you want to see some fairly idiomatic Python that does non-trivial stuff, there's Dive Into Python, although Dive Into Python 3 is newer and might be a better source of style tips. If you're looking more for some points to review, there's Code Like a Pythonista.
You could post your code at Refactor my code to see if someone can show you a more Pythonic way to do it.
Definitely not a panacea but I think you should try some code golf in Python. Obviously nobody should write "golfed" code IRL, but finding the most terse way to express something really forces you to exploit the built in functionality of the language.
Someone provided me with this list of how "Python is not Java" when I started Python after Java, and it was very helpful.
Also, check out this similar SO question that I posted a short time ago when in a similar position.
Try to find algorithms that you understand well and see how they are implemented in python standard libraries.
Persist. :)
Learn a few other languages. It will help you make the difference between algorithms (the structure of processing, unchanged between languages) and the local syntaxic features of the language. Then you can "write Foo in Bar" for any combination of languages "Foo" and "Bar".
Eat Python, Sleep Python and Drink Python. That is the only way........
This is useful if you want to understand how to code to python in a more pythonic or correct way: http://www.python.org/dev/peps/pep-0008/

Categories

Resources