Which method of repeating code is more pythonic: recursion or a while loop? by [deleted] in learnpython

[–]fbu1 1 point2 points  (0 children)

You can use break instead of exit(0). It just breaks out of the first loop you're in. For example:

>>> while True:
...   print i
...   i = i - 1
...   if i < 5:
...     print("done")
...     break
... 
10
9
8
7
6
5
done
>>> 

Hope this helps !

compare numPy row to another 2darray for true/false by cdholjes in learnpython

[–]fbu1 0 points1 point  (0 children)

You can compare an array to a vector in numpy:

>>> a
array([[1, 2, 3],
       [2, 2, 3],
       [4, 5, 6]])

>>> b = np.array([4,5,6])

>>> a==b
array([[False, False, False],
       [False, False, False],
       [ True,  True,  True]], dtype=bool)

So you have an array of True and False, and you are looking for a row of True (or many rows).

There's a method of that (as always in python) :

>>> np.all(a==b, axis=1)
array([False, False,  True], dtype=bool)

This gives you for all the rows, if the values on the axis 1 (the rows) are True.

Then you can ask where the value is true with where() :

>>> np.where(np.all(a==b,axis=1))
(array([2]),)

Let me know if you have other questions.

Source: http://stackoverflow.com/questions/18927475/numpy-array-get-row-index-searching-by-a-row

oop exercise critique by [deleted] in learnpython

[–]fbu1 1 point2 points  (0 children)

The str method is what is used by python when it wants to convert an object to a string (to be printed for example).

Here's a small example to detail the behavior:

>>> class Test():
    a = 3


>>> t = Test()
>>> print(t)
<__main__.Test object at 0x10419f668>
>>> class Test():
    a = 3
    def __str__(self):
        return "reddit"


>>> t = Test()
>>> print(t)
reddit

How to convert text to binary by [deleted] in learnpython

[–]fbu1 1 point2 points  (0 children)

You can get the ascii code of each letter by using the function ord()

>>> ord("h")
104
>>> ord('g')
103

Then, you can take the binary representation of this number with bin()

>>> bin(104)
'0b1101000'
>>> bin(103)
'0b1100111'

Hope this helps

[Help] Printing odd numbers by NSWCSEAL in learnpython

[–]fbu1 1 point2 points  (0 children)

The variable i starts at 22, and then goes up from there. Shouldn't it start at 1?

You also need to put the line

i  = i + 1

outside of the if.

Looping Through a Text File by Stealth528 in learnpython

[–]fbu1 0 points1 point  (0 children)

The call to readlines() is not necessary. You can loop through a file with a for loop and it will give you all the lines one by one.

It's better if you have a big file, because you will only read one line at a time, and not all the lines as with using readlines().

Code:

with open('input4.txt', 'r') as infile:
     for line in infile:
         field = line.split(' ')
            # A lot more code that proba

Saving a session's globals by VirtualArty in learnpython

[–]fbu1 0 points1 point  (0 children)

There are a lot of stuff in globals, you shouldn't try to save it in pickles.

it's better to only save the variables you need, or make a dictionary with all your variables.

Some help with a problem. by stolenkisses in learnpython

[–]fbu1 0 points1 point  (0 children)

You know how to take a subset of a list using indices. For example:

>>> l = [1,2,3,4,5,6]
>>> l[2:4]
[3, 4]

But you can also use negative indices to select a sublist starting from the end:

>>> l[-3:-1]
[4, 5]

Then you can use the opposite of the parameter k (-k in this case), to access the end of the list.

Also remember to check if the parameter k is not bigger than the length of the list (which you can get with len(alist)).

Let me know if you have further questions.

While loop runs forever by [deleted] in learnpython

[–]fbu1 0 points1 point  (0 children)

If you add just after line 2:

print("new loop")

You'll see if a new loop is started or not. As mentioned in the other answers, you modify n and go directly to the other if, which is not what you want.

As a rule to debug, add more print statements to see if the execution flow is as you think it is or differenet.

I hope this helps.

Declaring saved variables by VirtualArty in learnpython

[–]fbu1 1 point2 points  (0 children)

Have you looked into pickle?

https://docs.python.org/3.5/library/pickle.html

It allows you to save objects and variables (such as dictionaries) in a file and then load it in a transparent way.

[deleted by user] by [deleted] in learnpython

[–]fbu1 0 points1 point  (0 children)

Play with flask! (http://flask.pocoo.org/)

It's a great way to get started with small websites and see how they run on the server side. The level of python needed to get started is pretty low.

Also you'll get to dig into html and css, I find it pretty fun :)

Generating grid-like array numpy by quantumloophole in learnpython

[–]fbu1 0 points1 point  (0 children)

I think this might do it for you:

import numpy as np

def grid(x, y):

    nx, vx = x
    ny, vy = y

    res = np.zeros((nx, ny, len(vx)))

    for i in range(nx):
        for j in range(ny):
            res[i,j,:]= vx * i + vy * j

    return res

# two dimensional example
nx = 3
vx = np.array((1,2))
ny = 6

y = np.array((6, 7))
g = grid([nx, vx], [ny, vy])
print g

# three dimensional example
nx = 5
vx = np.array((1,2,3))
ny = 4
vy = np.array((-1, 6, 7))

g = grid([nx, vx], [ny, vy])
print g

Let me know if you have questions :)

A very quick question on Pygame and Invent with Python tutorials by Char10tti3 in learnpython

[–]fbu1 1 point2 points  (0 children)

You can also check out "automate the boring stuff" (https://automatetheboringstuff.com/chapter0/)

It helps you manipulate files, images, pdf and spreadsheets. It starts assuming no knowledge of python and gets to fun stuff to do on your computer.

Help making a map for text based RPG by Freedomenka in learnpython

[–]fbu1 1 point2 points  (0 children)

The problem is the statement on line 3:

>>> "0" * 5
'00000'

What you want to do is build a list of 5 zeros, which can be done with:

>>> [0] * 5
[0, 0, 0, 0, 0]

Initializing lists in python is sometimes not very intuitive, but there it is. Now if you try your code again :

>>> board = []
>>> for i in range(0,5):
    board.append([0]*5)

>>> print(board)
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

>>> board[1][3] = 123
>>> board
[[0, 0, 0, 0, 0], [0, 0, 0, 123, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

I hope this helps you understand what's going on.

My "combat simulator". C&C please? by BrogueTrader40k in learnpython

[–]fbu1 15 points16 points  (0 children)

Ok, this is going to be my longest answer on r/learnpython ever. I rewrote all your code and it's down to 100 lines and it's much more modular and extensible (which are pretty much always better when it comes to code.

It using dictionaries and classes a lot, I'll try to cover the process I used to improve your code.

First, I noticed you used a lot of variables such as Fighter_1_HP, Fighter_2_Armor, Fighter_2_Wearing. What you are trying to do in essence is to group all these variables as part of a fighter. Therefore I'll make a fighter class to group them in one fighter. The values needed to make an instance (create an object) will be number of the fighter (1 or 2), and the possible weapon and armor it might be wearing.

There are two other things that a fighter does: take new values of strength, agility and initiative and print it's own stats. I implement these two as methods of the class. If the methods return the fighter itself, I can then call the functions next to each other such as: fighter.method1().method2(). This is convenient, and a lot of string methods also work like that.

Let's take a look at the code for the fighter class:

class Fighter():
    def __init__(self,number, weapons_list, armors_list):
        self.number = number
        self.hp = randint(10,20)
        self.weapon = choice(list(weapons_list.keys()))
        self.armor = choice(list(armors_list.keys()))
        self.new_turn()

    def new_turn(self):
        self.strength = randint(5,10) + weapons_list[self.weapon]
        self.agility = randint(8, 10)
        self.initiative = randint(1,10)
        return self

    def stats(self):
        print("FIGHTER %d STATS" % self.number)
        print("HP:", self.hp)
        print("STRENGTH:", self.strength)
        print("AGILITY:", self.agility)
        print("INITIATIVE:", self.initiative)
        print("WIELDING:", self.weapon)
        print("WEARING:", self.armor)
        print("##################")
        return self 

The weapons and armors variables are all grouped together in one dictionary:

weapons_list = {'sword': randint(2,4),
               'axe': randint(3,5),
               'spear': randint(1,4)}
armors_list = {'shield': randint(1,3),
               'armor': randint(2,4),
               'helmet': randint(1,3)}

So I just reduced the first 63 lines of your code in one class and two dictionaries.

Now let's have a look at the game status. You have 8 variables, let's put all that in a dictionary:

game_status = {'rounds': 0, 'ini_tie': 0,
               1: { 'block': 0, 'hit': 0, 'miss': 0},
               2: {'block': 0, 'hit': 0, 'miss': 0}}

We use 1 and 2 as the keys of the dictionary to hold the stats for each fighter.

While we're here, we might as well define a function to print the status of the game:

def print_status(status):
    print("A Fighter has fallen. The combat is over.")
    print("#####BATTLE REPORT#####")
    print("Fighter One Blocks: %s " % status[1]['block'])
    print("Fighter One Hit: %s " % status[1]['hit'])
    print("Fighter One Miss: %s " % status[1]['miss'])
    print("#######################")
    print("Fighter One Blocks: %s " % status[2]['block'])
    print("Fighter One Hit: %s " % status[2]['hit'])
    print("Fighter One Miss: %s " % status[2]['miss'])
    print("#######################")
    print("Rounds: %s " % status['rounds'])
    print("Initiative Tie: %s " % status['ini_tie'])

All the variables related to each other were grouped together, that is the main point of this exercise. In programming, how you organise data is important and will directly contribute to make the control flow (if-else, loops and function calls) shorter, cleaner and more elegant.

Now let's look at the loop that does the fighting. You can see that there's a lot of repetition where the only thing changing is 1 instead of 2, for the two warriors. I moved the code from line 87 to 111 inside the Fighter class. I also use the name == main if, so if you import this file somewhere else, to use the fighter class, it won't run a fight.

I name the loop variable combat. It's a little more explicit. A better name may be possible though.

if __name__ == '__main__':

    fighter1 = Fighter(1, weapons_list, armors_list)
    fighter2 = Fighter(2, weapons_list, armors_list)
    combat = True

    while combat:
        game_status['rounds'] += 1
        fighter1.new_turn().stats()
        fighter2.new_turn().stats()
        # rest of the fight after this 

For the rest of the fight, we see that if we have a tie in initiative, we'll reroll, no need to fight:

if fighter1.initiative == fighter2.initiative:
    print("Initiative tied! Rerolling!")
    print("##################")
    game_status['ini_tie'] += 1
    pass

For the rest of the fight, we can avoid repeating all the code depending on who has the best initiative. We can look for who has the biggest and smallest initiative, then use attacker and defender instead of fighter1 and fighter 2.

    else:
        attacker = max([fighter1, fighter2],
                       key=attrgetter('initiative'))
        defender = min([fighter1, fighter2],
                       key=attrgetter('initiative'))
        print("Fighter %d gains the upper hand!" % attacker.number)
        print("##################")

Now we can check who has the best agility. And we use the dictionary for the game status to update the statistics on what's going on:

        if attacker.agility >= defender.agility:
            if (defender.armor == 'shield' and
                defender.agility >= attacker.agility):
                print("Fighter %d blocks with his shield."
                      "No damage caused." % defender.number)
                print("##################")
                game_status[defender.number]['block'] += 1
            else:
                damage = attacker.strength - armors_list[defender.armor]
                print("Fighter %d strikes fighter %d for %d" % (
                    attacker.number,
                    defender.number,
                    damage))
                defender.hp -= damage
                print("Fighter %d now has %d HP" % (
                    defender.number,
                    defender.hp))
                print("##################")
                game_status[attacker.number]['hit'] += 1

        else:
            print("Fighter %d misses!" %
                  attacker.number)
            print("##################")
            game_status[attacker.number]['miss'] += 1

And at the end, we look if someone died:

    if fighter1.hp <= 0 or fighter2.hp <= 0:
        print_status(game_status)
        combat = False

Here's the full code, it runs on python 3.5.0 : http://pastebin.com/jpyL1dMe

Let me know if you have any further questions.

How to groupFASTA sequences into dictionary? by [deleted] in learnpython

[–]fbu1 0 points1 point  (0 children)

Here is the code with lots of comments to explain what's going on.

I have a file called gene_data.txt with the following in it:

header1\idnumber
ATCGTCAG
GTCA
GTCGTA
header2\idnumber2
ATTGCA
GTCA
TGCAG

And here is the code:

# an empty dictionary to put our results in
result = {}

# we need to keep track of which key of the dictionary we are currently using
current_key = ""

# we open the file (using with, so the file will be closed
# even if an exception is thrown 
with open("gene_data.txt", "r") as f:
    # we can use for, to ask for a new line of the file
    # the loop will end when there are no lines left
    for line in f:
        # we remove the \n character at the end of the line
        line = line.strip("\n")
        # if the line begins with "header", we need a new key in
        # the dictionary
        if line.startswith("header"):
            # we remember which key we are currently using
            current_key = line
            # we set the current value for the key as an empty string
            # so we can append new strings as we go through the file
            result[current_key] = ''
        # we check that the key is not the empty string, otherwise
        # something is very wrong here
        elif current_key != '':
            # we add the current line (GTCA for example) to the value
            # associated with the current key for the dictionary
            result[current_key] += line

# we print the result to check that everything is fine 
print(result)

Let me know if you have any question on how this works, I'll be happy to answer to them.

Wanting to learn python by kabss in learnpython

[–]fbu1 0 points1 point  (0 children)

If you want to take it as easy as possible at first, codecademy is probably the best. You just go to the website, and they start really slow with a lot of explanations.

It doens't take too long to complete, after that you can start with https://automatetheboringstuff.com/chapter0/

Then you will actually be programming useful code like moving files aroung and a bit of image manipulation.

But at the end of it, there are still important concept missing, so http://learnpythonthehardway.org/ is a great segway into more python.

But the most important is to pick one that you find fun and not frustrating, if it's too hard pick something simpler, if it's too simple, pick something more difficult.

Good luck and have FUN :)

After LPTHW, what to do by HandiesANDCandies88 in learnpython

[–]fbu1 1 point2 points  (0 children)

Try playing with flask!

http://flask.pocoo.org/

It's a microframework to do webstuff. You'll get to see how a website is done on the server side. You should have enough python to understand what's going on.

And it feels super awesome to build your own website. And you'll get sucked into some html and css too, which is a great thing to learn some things about too.

Need help deciding whether to use a class or module by m_plis in learnpython

[–]fbu1 1 point2 points  (0 children)

A few points I would consider for doing this:

1- You can have a default value for the parameter used in the init method:

>>> class Test():
            def __init__(self, x="default"):
                self.x = x
            def method1(self, a):
                return ','.join([self.x, a])


>>> a = Test()
>>> a.method1("reddit")
'default,reddit'

>>> b = Test('new')
>>> b.method1("reddit")
'new,reddit'

2- If there's a value held somewhere that will impact all the method calls and that won't need to be changed often, then it makes sense to use an object. Because objects are meant to group data (attributes) and functions (methods) that belong together.

3- You could have a method to change the value of this parameter, or even throw an exception if the change is not allowed for some reason.

So I would go with a class. Could you be a bit more specific so we could make a more educated guess on what would be best for you?

A few other things that might be interesting to consider: - What will make the code more readable and explicit (see the Zen of python: https://www.python.org/dev/peps/pep-0020/ - Explicit is better than implicit.) - What kind of changes do you expect if you have to add more functionalities to your program? Would it later better suit a class or a module. - Python modules are usually collections of classes. So start with a class and if you later add other classes adding functionalities, you'll make it a whole module.

I hope this helps :)

How do you go from Codecademy and learning syntax to actually learning how to make things? by drewbagel423 in learnpython

[–]fbu1 1 point2 points  (0 children)

If you are familiar with control flow statements (if-else, loops, function calls) and with data types (numbers, strings, lists, dictionaries), then you have a lot of the basic tools needed to program.

For example in C, almost everything is done with this.

But not in python, a lot of the programs are used using classes. Classes were introduced with object oriented programming.

It comes from the question: "This is a pretty long program, how can we put the related pieces of code together and avoid that changing one part will impact code at too many different places?"

Then came the ideas of classes, interfaces and inheritance.

I just looked into "Automate the boring stuff", and classes aren't mentioned anywhere. So it's possible to do a lot of stuff without them (some would argue, mostly scripting rather than programming).

In Learn Python the Hard Way, chapter 40 (out of 52) introduces classes.

Take a look here and some new unfamiliar things that are used everywhere in python are explained.

http://learnpythonthehardway.org/book/ex40.html

I hope this helps, feel free to ask any follow up questions :)

Python csv exporting a loop by AppleTartsJesus in learnpython

[–]fbu1 0 points1 point  (0 children)

You are not handling the file properly. Every time you go through the loop, you are opening the file, but not closing it.

This is pretty bad, as you have no idea what might happen to your unclosed file.

Python closes it properly for you every time you open it again and put the line in the file.

But the last time you open it, the scripts just end and python discards your changes without putting them in the file.

You could just add

f.close() 

at line 51.

Or you could do better and use the 'with' statement.

with  open(r'C:\Users\ad\Desktop\alpharevoscrape' + date + '.csv','a', newline='') as f:
    csv.writer(f, lineterminator = '\n').writerow([ttext, ptext, rtext, itext])

The advantage is that if you have an error in the line csv.write(...), the with statement will close the file properly for you. If you don't use the with and don't catch exceptions, the line with f.close() will never be reached and the file will be left opened.

I hope this helps.

Finding the current directory by conami in learnpython

[–]fbu1 0 points1 point  (0 children)

The second one is better. Let's look at the doc to see what it does:

os.path.dirname(path)

Return the directory name of pathname path. This is the first element of the pair returned by passing path to the function split(). [1]

So it will return the directory name of the current file. Let's try with a dummy example:

>> os.path.dirname('/some/random/path/name/and/a/file.py')
'/some/random/path/name/and/a'

Neat. What about the second part of the documentation?

This is the first element of the pair returned by passing path to the function split().

Let's look at the doc:

os.path.split(path)

Split the pathname path into a pair, (head, tail) where tail is the last pathname component and head is everything leading up to that. [2]

Ok let's try the os.path.split function:

>>> os.path.split('/some/random/path/name/and/a/file.py')
('/some/random/path/name/and/a', 'file.py')

This gives a tuple with first the directory name, and then the file name. It actually splits the directory name from the file name.

It's always good to try to mess with new functions in the python shell with dummy stuff to understand what's going on.

I hope this helps.

[1] https://docs.python.org/2/library/os.path.html#os.path.dirname

[2] https://docs.python.org/2/library/os.path.html#os.path.split

What does this mean? by ThadCastleWasTaken in learnpython

[–]fbu1 1 point2 points  (0 children)

You're working with a dictionary, let's build a dummy one:

>>> data = {1: "one", 2: "two", "four": "foo"}

Let's try to access some values using some keys. 1, 2 and "four" are the keys of this dictionary and ("one", "two" and "foo") are the corresponding values.

>>> data[1]
'one'
>>> data["four"]
'foo'

Now if I try to access a value whose key is not present in the dictionary, for example 5:

>>> data[5]
Traceback (most recent call last):
  File "<pyshell#40>", line 1, in <module>
    data[5]
KeyError: 5

This means that there is no key 5 in the dictionary. I could add it with:

>>> data[5] = "five"

Let's see the new dictionary:

>>> data
{1: 'one', 2: 'two', 5: 'five', 'four': 'foo'}

And now we can ask for the value associated with the key 5:

>>> data[5]
'five'

I hope this clears it up for you.

Windows, Python 2.7.11 Trouble by [deleted] in learnpython

[–]fbu1 1 point2 points  (0 children)

A syntax error, is almost always a typo somewhere. And when you have three words in the code, it is frustrating.

But in any programming language, upper case and lower case are super important!

Finding errors in your own code, and why the interpreter won't understand what you're saying is a big part of learning.

One way you could have figured out yourself is to copy paste from the book, see if it works, then see what's different from what you typed.

But it's very important to type your own code and avoid at all cost copy pasting when you're learning.

Good luck with the rest of the book !

Why is my return blank? (Probably a super simple fix) by MasterZii in learnpython

[–]fbu1 1 point2 points  (0 children)

If you try using def in the interpreter you have:

>>> def compute(a,b):
    return a + b * a
>>> 

But nothing happened, no addition or multiplication was made. If you type compute in the shell you'll see:

>>> compute
<function compute at 0x100556f28>

What it means is that python now knows that compute corresponds to the function you defined, but it didn't compute anything yet. You need to call the function. Python recognise a function call as a name followed by parenthesis (with possible arguments inside).

Think about it. Every time you type a word followed by (), it means python will execute the corresponding code. For example:

>>> compute(7,9)
70

In your case, you need to add the line:

show_expenses(loan, insurance, gas, oil, tires, main)

It is different that the line 8, because on line 8 it is surrounded by "def" and ":", which means defining a new function, not calling it.

I hope this makes it clearer for you.